Mercurial > projects > pwm
annotate rand-dev-random.c @ 25:616385fa1fd9
Build common functions as a library that can be reused
author | Guido Berhoerster <guido+pwm@berhoerster.name> |
---|---|
date | Wed, 20 Sep 2017 23:57:51 +0200 |
parents | 8768fbd09bc5 |
children |
rev | line source |
---|---|
12
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
1 /* |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
2 * Copyright (C) 2017 Guido Berhoerster <guido+pwm@berhoerster.name> |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
3 * |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
4 * Permission is hereby granted, free of charge, to any person obtaining |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
5 * a copy of this software and associated documentation files (the |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
6 * "Software"), to deal in the Software without restriction, including |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
7 * without limitation the rights to use, copy, modify, merge, publish, |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
8 * distribute, sublicense, and/or sell copies of the Software, and to |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
9 * permit persons to whom the Software is furnished to do so, subject to |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
10 * the following conditions: |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
11 * |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
12 * The above copyright notice and this permission notice shall be included |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
13 * in all copies or substantial portions of the Software. |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
14 * |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
22 */ |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
23 |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
24 #include "compat.h" |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
25 |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
26 #ifdef HAVE_ERR_H |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
27 #include <err.h> |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
28 #endif /* HAVE_ERR_H */ |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
29 #include <errno.h> |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
30 #include <fcntl.h> |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
31 #include <sys/stat.h> |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
32 #include <unistd.h> |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
33 |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
34 #include "rand.h" |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
35 |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
36 #ifdef __linux__ |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
37 #define PATH_DEV_RANDOM "/dev/urandom" |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
38 #else |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
39 #define PATH_DEV_RANDOM "/dev/random" |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
40 #endif /* __linux__ */ |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
41 |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
42 void |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
43 rand_buf(void *buf, size_t buf_size) |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
44 { |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
45 unsigned char *p = buf; |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
46 int fd; |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
47 ssize_t nread; |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
48 size_t nsize = buf_size; |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
49 |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
50 do { |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
51 fd = open(PATH_DEV_RANDOM, O_RDONLY); |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
52 } while ((fd < 0) && (errno == EINTR)); |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
53 if (fd < 0) { |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
54 err(1, "open"); |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
55 } |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
56 |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
57 while (nsize > 0) { |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
58 nread = read(fd, p, nsize); |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
59 if (nread < 0) { |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
60 if (errno == EINTR) { |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
61 continue; |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
62 } |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
63 err(1, "read"); |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
64 } |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
65 p += nread; |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
66 nsize -= nread; |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
67 } |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
68 |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
69 while ((close(fd) < 0) && (errno == EINTR)); |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
70 } |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
71 |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
72 uint32_t |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
73 rand_random(void) |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
74 { |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
75 uint32_t x; |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
76 |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
77 rand_buf(&x, sizeof (x)); |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
78 |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
79 return (x); |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
80 } |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
81 |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
82 /* random number between 0 and upper_bound - 1 without modulo bias */ |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
83 uint32_t |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
84 rand_uniform(uint32_t upper_bound) |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
85 { |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
86 uint32_t r; |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
87 /* (2^32 - upper_bound) % upper_bound */ |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
88 uint32_t threshold = -upper_bound % upper_bound; |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
89 |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
90 do { |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
91 r = rand_random(); |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
92 } while (r < threshold); |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
93 |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
94 return (r % upper_bound); |
8768fbd09bc5
Add generatepassword command to generate random passwords
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff
changeset
|
95 } |