xcrypt 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +106 -0
  3. data/ext/libxcrypt/AUTHORS +38 -0
  4. data/ext/libxcrypt/COPYING.LIB +502 -0
  5. data/ext/libxcrypt/ChangeLog +239 -0
  6. data/ext/libxcrypt/INSTALL +380 -0
  7. data/ext/libxcrypt/LICENSING +152 -0
  8. data/ext/libxcrypt/Makefile.am +704 -0
  9. data/ext/libxcrypt/Makefile.in +4110 -0
  10. data/ext/libxcrypt/NEWS +630 -0
  11. data/ext/libxcrypt/README +1 -0
  12. data/ext/libxcrypt/README.md +179 -0
  13. data/ext/libxcrypt/THANKS +13 -0
  14. data/ext/libxcrypt/TODO +1 -0
  15. data/ext/libxcrypt/TODO.md +100 -0
  16. data/ext/libxcrypt/aclocal.m4 +2617 -0
  17. data/ext/libxcrypt/autogen.sh +33 -0
  18. data/ext/libxcrypt/autom4te.cache/output.0 +19884 -0
  19. data/ext/libxcrypt/autom4te.cache/output.1 +19884 -0
  20. data/ext/libxcrypt/autom4te.cache/output.2 +19884 -0
  21. data/ext/libxcrypt/autom4te.cache/output.3 +19885 -0
  22. data/ext/libxcrypt/autom4te.cache/requests +714 -0
  23. data/ext/libxcrypt/autom4te.cache/traces.0 +4088 -0
  24. data/ext/libxcrypt/autom4te.cache/traces.1 +1060 -0
  25. data/ext/libxcrypt/autom4te.cache/traces.2 +4088 -0
  26. data/ext/libxcrypt/autom4te.cache/traces.3 +1060 -0
  27. data/ext/libxcrypt/build-aux/ci/ci-log-dependency-versions +79 -0
  28. data/ext/libxcrypt/build-aux/ci/ci-log-logfiles +22 -0
  29. data/ext/libxcrypt/build-aux/ci/clang-gcov-wrapper +2 -0
  30. data/ext/libxcrypt/build-aux/ci/configure-wrapper +10 -0
  31. data/ext/libxcrypt/build-aux/ci/summarize-coverage +24 -0
  32. data/ext/libxcrypt/build-aux/m4/ax_append_compile_flags.m4 +46 -0
  33. data/ext/libxcrypt/build-aux/m4/ax_append_flag.m4 +50 -0
  34. data/ext/libxcrypt/build-aux/m4/ax_check_compile_flag.m4 +53 -0
  35. data/ext/libxcrypt/build-aux/m4/ax_check_vscript.m4 +142 -0
  36. data/ext/libxcrypt/build-aux/m4/ax_gcc_func_attribute.m4 +246 -0
  37. data/ext/libxcrypt/build-aux/m4/ax_require_defined.m4 +37 -0
  38. data/ext/libxcrypt/build-aux/m4/ax_valgrind_check.m4 +239 -0
  39. data/ext/libxcrypt/build-aux/m4/libtool.m4 +8488 -0
  40. data/ext/libxcrypt/build-aux/m4/ltoptions.m4 +467 -0
  41. data/ext/libxcrypt/build-aux/m4/ltsugar.m4 +124 -0
  42. data/ext/libxcrypt/build-aux/m4/ltversion.m4 +24 -0
  43. data/ext/libxcrypt/build-aux/m4/lt~obsolete.m4 +99 -0
  44. data/ext/libxcrypt/build-aux/m4/pkg_compat.m4 +88 -0
  45. data/ext/libxcrypt/build-aux/m4/zw_alignment.m4 +90 -0
  46. data/ext/libxcrypt/build-aux/m4/zw_automodern.m4 +307 -0
  47. data/ext/libxcrypt/build-aux/m4/zw_detect_asan.m4 +24 -0
  48. data/ext/libxcrypt/build-aux/m4/zw_endianness.m4 +152 -0
  49. data/ext/libxcrypt/build-aux/m4/zw_ld_wrap.m4 +47 -0
  50. data/ext/libxcrypt/build-aux/m4/zw_prog_perl.m4 +40 -0
  51. data/ext/libxcrypt/build-aux/m4/zw_simple_warnings.m4 +150 -0
  52. data/ext/libxcrypt/build-aux/m4/zw_static_assert.m4 +68 -0
  53. data/ext/libxcrypt/build-aux/m4-autogen/compile +364 -0
  54. data/ext/libxcrypt/build-aux/m4-autogen/config.guess +1815 -0
  55. data/ext/libxcrypt/build-aux/m4-autogen/config.sub +2354 -0
  56. data/ext/libxcrypt/build-aux/m4-autogen/depcomp +792 -0
  57. data/ext/libxcrypt/build-aux/m4-autogen/install-sh +541 -0
  58. data/ext/libxcrypt/build-aux/m4-autogen/ltmain.sh +11524 -0
  59. data/ext/libxcrypt/build-aux/m4-autogen/missing +236 -0
  60. data/ext/libxcrypt/build-aux/m4-autogen/test-driver +160 -0
  61. data/ext/libxcrypt/build-aux/scripts/BuildCommon.pm +712 -0
  62. data/ext/libxcrypt/build-aux/scripts/check-perlcritic-config +76 -0
  63. data/ext/libxcrypt/build-aux/scripts/compute-symver-floor +116 -0
  64. data/ext/libxcrypt/build-aux/scripts/expand-selected-hashes +80 -0
  65. data/ext/libxcrypt/build-aux/scripts/gen-crypt-h +131 -0
  66. data/ext/libxcrypt/build-aux/scripts/gen-crypt-hashes-h +141 -0
  67. data/ext/libxcrypt/build-aux/scripts/gen-crypt-symbol-vers-h +150 -0
  68. data/ext/libxcrypt/build-aux/scripts/gen-libcrypt-map +67 -0
  69. data/ext/libxcrypt/build-aux/scripts/move-if-change +84 -0
  70. data/ext/libxcrypt/build-aux/scripts/skip-if-exec-format-error +78 -0
  71. data/ext/libxcrypt/codecov.yml +4 -0
  72. data/ext/libxcrypt/config.h.in +303 -0
  73. data/ext/libxcrypt/configure +19885 -0
  74. data/ext/libxcrypt/configure.ac +549 -0
  75. data/ext/libxcrypt/doc/crypt.3 +512 -0
  76. data/ext/libxcrypt/doc/crypt.5 +343 -0
  77. data/ext/libxcrypt/doc/crypt_checksalt.3 +106 -0
  78. data/ext/libxcrypt/doc/crypt_gensalt.3 +285 -0
  79. data/ext/libxcrypt/doc/crypt_gensalt_ra.3 +1 -0
  80. data/ext/libxcrypt/doc/crypt_gensalt_rn.3 +1 -0
  81. data/ext/libxcrypt/doc/crypt_preferred_method.3 +68 -0
  82. data/ext/libxcrypt/doc/crypt_r.3 +1 -0
  83. data/ext/libxcrypt/doc/crypt_ra.3 +1 -0
  84. data/ext/libxcrypt/doc/crypt_rn.3 +1 -0
  85. data/ext/libxcrypt/lib/alg-des-tables.c +3858 -0
  86. data/ext/libxcrypt/lib/alg-des.c +269 -0
  87. data/ext/libxcrypt/lib/alg-des.h +74 -0
  88. data/ext/libxcrypt/lib/alg-gost3411-2012-const.h +313 -0
  89. data/ext/libxcrypt/lib/alg-gost3411-2012-core.c +238 -0
  90. data/ext/libxcrypt/lib/alg-gost3411-2012-core.h +51 -0
  91. data/ext/libxcrypt/lib/alg-gost3411-2012-hmac.c +78 -0
  92. data/ext/libxcrypt/lib/alg-gost3411-2012-hmac.h +46 -0
  93. data/ext/libxcrypt/lib/alg-gost3411-2012-precalc.h +1426 -0
  94. data/ext/libxcrypt/lib/alg-gost3411-2012-ref.h +67 -0
  95. data/ext/libxcrypt/lib/alg-hmac-sha1.c +140 -0
  96. data/ext/libxcrypt/lib/alg-hmac-sha1.h +35 -0
  97. data/ext/libxcrypt/lib/alg-md4.c +270 -0
  98. data/ext/libxcrypt/lib/alg-md4.h +43 -0
  99. data/ext/libxcrypt/lib/alg-md5.c +291 -0
  100. data/ext/libxcrypt/lib/alg-md5.h +43 -0
  101. data/ext/libxcrypt/lib/alg-sha1.c +288 -0
  102. data/ext/libxcrypt/lib/alg-sha1.h +34 -0
  103. data/ext/libxcrypt/lib/alg-sha256.c +630 -0
  104. data/ext/libxcrypt/lib/alg-sha256.h +123 -0
  105. data/ext/libxcrypt/lib/alg-sha512.c +311 -0
  106. data/ext/libxcrypt/lib/alg-sha512.h +81 -0
  107. data/ext/libxcrypt/lib/alg-sm3-hmac.c +113 -0
  108. data/ext/libxcrypt/lib/alg-sm3-hmac.h +42 -0
  109. data/ext/libxcrypt/lib/alg-sm3.c +449 -0
  110. data/ext/libxcrypt/lib/alg-sm3.h +63 -0
  111. data/ext/libxcrypt/lib/alg-yescrypt-common.c +713 -0
  112. data/ext/libxcrypt/lib/alg-yescrypt-opt.c +1568 -0
  113. data/ext/libxcrypt/lib/alg-yescrypt-platform.c +106 -0
  114. data/ext/libxcrypt/lib/alg-yescrypt.h +360 -0
  115. data/ext/libxcrypt/lib/byteorder.h +164 -0
  116. data/ext/libxcrypt/lib/crypt-bcrypt.c +1061 -0
  117. data/ext/libxcrypt/lib/crypt-des-obsolete.c +215 -0
  118. data/ext/libxcrypt/lib/crypt-des.c +491 -0
  119. data/ext/libxcrypt/lib/crypt-gensalt-static.c +40 -0
  120. data/ext/libxcrypt/lib/crypt-gost-yescrypt.c +182 -0
  121. data/ext/libxcrypt/lib/crypt-md5.c +232 -0
  122. data/ext/libxcrypt/lib/crypt-nthash.c +134 -0
  123. data/ext/libxcrypt/lib/crypt-obsolete.h +40 -0
  124. data/ext/libxcrypt/lib/crypt-pbkdf1-sha1.c +260 -0
  125. data/ext/libxcrypt/lib/crypt-port.h +514 -0
  126. data/ext/libxcrypt/lib/crypt-scrypt.c +247 -0
  127. data/ext/libxcrypt/lib/crypt-sha256.c +308 -0
  128. data/ext/libxcrypt/lib/crypt-sha512.c +323 -0
  129. data/ext/libxcrypt/lib/crypt-sm3-yescrypt.c +189 -0
  130. data/ext/libxcrypt/lib/crypt-sm3.c +308 -0
  131. data/ext/libxcrypt/lib/crypt-static.c +44 -0
  132. data/ext/libxcrypt/lib/crypt-sunmd5.c +314 -0
  133. data/ext/libxcrypt/lib/crypt-yescrypt.c +177 -0
  134. data/ext/libxcrypt/lib/crypt.c +421 -0
  135. data/ext/libxcrypt/lib/crypt.h.in +249 -0
  136. data/ext/libxcrypt/lib/gen-des-tables.c +363 -0
  137. data/ext/libxcrypt/lib/hashes.conf +59 -0
  138. data/ext/libxcrypt/lib/libcrypt.map.in +48 -0
  139. data/ext/libxcrypt/lib/libcrypt.minver +97 -0
  140. data/ext/libxcrypt/lib/libxcrypt.pc.in +15 -0
  141. data/ext/libxcrypt/lib/util-base64.c +26 -0
  142. data/ext/libxcrypt/lib/util-gensalt-sha.c +88 -0
  143. data/ext/libxcrypt/lib/util-get-random-bytes.c +154 -0
  144. data/ext/libxcrypt/lib/util-make-failure-token.c +48 -0
  145. data/ext/libxcrypt/lib/util-xbzero.c +43 -0
  146. data/ext/libxcrypt/lib/util-xstrcpy.c +42 -0
  147. data/ext/libxcrypt/lib/xcrypt.h.in +58 -0
  148. data/ext/libxcrypt/libxcrypt.spec.rpkg +481 -0
  149. data/ext/libxcrypt/rpkg.conf +2 -0
  150. data/ext/libxcrypt/rpkg.macros +86 -0
  151. data/ext/libxcrypt/test/TestCommon.pm +326 -0
  152. data/ext/libxcrypt/test/alg-des.c +80 -0
  153. data/ext/libxcrypt/test/alg-gost3411-2012-hmac.c +90 -0
  154. data/ext/libxcrypt/test/alg-gost3411-2012.c +191 -0
  155. data/ext/libxcrypt/test/alg-hmac-sha1.c +187 -0
  156. data/ext/libxcrypt/test/alg-md4.c +111 -0
  157. data/ext/libxcrypt/test/alg-md5.c +134 -0
  158. data/ext/libxcrypt/test/alg-pbkdf-hmac-sha256.c +269 -0
  159. data/ext/libxcrypt/test/alg-sha1.c +111 -0
  160. data/ext/libxcrypt/test/alg-sha256.c +141 -0
  161. data/ext/libxcrypt/test/alg-sha512.c +170 -0
  162. data/ext/libxcrypt/test/alg-sm3-hmac.c +149 -0
  163. data/ext/libxcrypt/test/alg-sm3.c +168 -0
  164. data/ext/libxcrypt/test/alg-yescrypt.c +466 -0
  165. data/ext/libxcrypt/test/badsalt.c +726 -0
  166. data/ext/libxcrypt/test/badsetting.c +350 -0
  167. data/ext/libxcrypt/test/byteorder.c +254 -0
  168. data/ext/libxcrypt/test/checksalt.c +265 -0
  169. data/ext/libxcrypt/test/compile-strong-alias.c +43 -0
  170. data/ext/libxcrypt/test/crypt-badargs.c +392 -0
  171. data/ext/libxcrypt/test/crypt-gost-yescrypt.c +149 -0
  172. data/ext/libxcrypt/test/crypt-nested-call.c +180 -0
  173. data/ext/libxcrypt/test/crypt-sm3-yescrypt.c +149 -0
  174. data/ext/libxcrypt/test/crypt-too-long-phrase.c +157 -0
  175. data/ext/libxcrypt/test/des-cases.h +196 -0
  176. data/ext/libxcrypt/test/des-obsolete.c +206 -0
  177. data/ext/libxcrypt/test/des-obsolete_r.c +207 -0
  178. data/ext/libxcrypt/test/explicit-bzero.c +334 -0
  179. data/ext/libxcrypt/test/gensalt-bcrypt_x.c +54 -0
  180. data/ext/libxcrypt/test/gensalt-extradata.c +246 -0
  181. data/ext/libxcrypt/test/gensalt-nested-call.c +126 -0
  182. data/ext/libxcrypt/test/gensalt-nthash.c +65 -0
  183. data/ext/libxcrypt/test/gensalt.c +599 -0
  184. data/ext/libxcrypt/test/getrandom-fallbacks.c +295 -0
  185. data/ext/libxcrypt/test/getrandom-interface.c +211 -0
  186. data/ext/libxcrypt/test/ka-table-gen.py +945 -0
  187. data/ext/libxcrypt/test/ka-table.inc +5849 -0
  188. data/ext/libxcrypt/test/ka-tester.c +240 -0
  189. data/ext/libxcrypt/test/preferred-method.c +133 -0
  190. data/ext/libxcrypt/test/short-outbuf.c +119 -0
  191. data/ext/libxcrypt/test/special-char-salt.c +1160 -0
  192. data/ext/libxcrypt/test/symbols-compat.pl +137 -0
  193. data/ext/libxcrypt/test/symbols-renames.pl +107 -0
  194. data/ext/libxcrypt/test/symbols-static.pl +87 -0
  195. data/ext/xcrypt/xcrypt.c +9 -0
  196. data/lib/xcrypt/ffi.rb +76 -0
  197. data/lib/xcrypt/version.rb +5 -0
  198. data/lib/xcrypt.rb +89 -0
  199. metadata +267 -0
@@ -0,0 +1,295 @@
1
+ /* Test the fallback logic in get_random_bytes.
2
+
3
+ Written by Zack Weinberg <zackw at panix.com> in 2018.
4
+ To the extent possible under law, Zack Weinberg has waived all
5
+ copyright and related or neighboring rights to this work.
6
+
7
+ See https://creativecommons.org/publicdomain/zero/1.0/ for further
8
+ details. */
9
+
10
+ #include "crypt-port.h"
11
+
12
+ #include <stdarg.h>
13
+ #include <stdio.h>
14
+ #include <string.h>
15
+ #include <errno.h>
16
+
17
+ #ifdef HAVE_FCNTL_H
18
+ #include <fcntl.h>
19
+ #endif
20
+ #if defined HAVE_SYS_SYSCALL_H
21
+ #include <sys/syscall.h>
22
+ #endif
23
+ #ifdef HAVE_SYS_STAT_H
24
+ #include <sys/stat.h>
25
+ #endif
26
+
27
+ /* If arc4random_buf is available, all of the fallback logic is compiled
28
+ out and this test is unnecessary. If ld --wrap is not available this
29
+ test will not work. */
30
+ #if defined HAVE_ARC4RANDOM_BUF || !defined HAVE_LD_WRAP
31
+
32
+ int
33
+ main (void)
34
+ {
35
+ return 77;
36
+ }
37
+
38
+ #else
39
+
40
+ /* All of the mock system primitives below fill in their buffer with
41
+ repeats of these bytes, so we can tell where the data came from. */
42
+ #define MOCK_getentropy 'e'
43
+ #define MOCK_getrandom 'r'
44
+ #define MOCK_sys_getentropy 'E'
45
+ #define MOCK_sys_getrandom 'R'
46
+ #define MOCK_urandom 'u'
47
+
48
+ #ifdef HAVE_GETENTROPY
49
+ static bool getentropy_should_fail = false;
50
+ extern int __wrap_getentropy (void *, size_t);
51
+ int
52
+ __wrap_getentropy (void *buf, size_t buflen)
53
+ {
54
+ if (getentropy_should_fail)
55
+ {
56
+ errno = ENOSYS;
57
+ return -1;
58
+ }
59
+ else
60
+ {
61
+ memset (buf, MOCK_getentropy, buflen);
62
+ return 0;
63
+ }
64
+ }
65
+ #endif
66
+
67
+ #ifdef HAVE_GETRANDOM
68
+ static bool getrandom_should_fail = false;
69
+ extern ssize_t __wrap_getrandom (void *, size_t, unsigned int);
70
+ ssize_t
71
+ __wrap_getrandom (void *buf, size_t buflen, unsigned int ARG_UNUSED(flags))
72
+ {
73
+ if (getrandom_should_fail)
74
+ {
75
+ errno = ENOSYS;
76
+ return -1;
77
+ }
78
+ else
79
+ {
80
+ buflen = MIN (buflen, INT16_MAX);
81
+ memset (buf, MOCK_getrandom, buflen);
82
+ return (ssize_t)buflen;
83
+ }
84
+ }
85
+ #endif
86
+
87
+ #ifdef HAVE_SYSCALL
88
+ #ifdef SYS_getentropy
89
+ static bool sys_getentropy_should_fail = false;
90
+ #endif
91
+ #ifdef SYS_getrandom
92
+ static bool sys_getrandom_should_fail = false;
93
+ #endif
94
+ static bool other_syscalls = false;
95
+ extern long __wrap_syscall (long, ...);
96
+ long
97
+ __wrap_syscall(long number, ...)
98
+ {
99
+ #ifdef SYS_getentropy
100
+ if (number == SYS_getentropy)
101
+ {
102
+ if (sys_getentropy_should_fail)
103
+ {
104
+ errno = ENOSYS;
105
+ return -1;
106
+ }
107
+ else
108
+ {
109
+ va_list ap;
110
+ va_start (ap, number);
111
+ void *buf = va_arg (ap, void *);
112
+ size_t buflen = va_arg (ap, size_t);
113
+ va_end (ap);
114
+ memset (buf, MOCK_sys_getentropy, buflen);
115
+ return 0;
116
+ }
117
+ }
118
+ #endif
119
+ #ifdef SYS_getrandom
120
+ if (number == SYS_getrandom)
121
+ {
122
+ if (sys_getrandom_should_fail)
123
+ {
124
+ errno = ENOSYS;
125
+ return -1;
126
+ }
127
+ else
128
+ {
129
+ va_list ap;
130
+ va_start (ap, number);
131
+ void *buf = va_arg (ap, void *);
132
+ size_t buflen = va_arg (ap, size_t);
133
+ buflen = MIN (buflen, INT16_MAX);
134
+ va_end (ap);
135
+ memset (buf, MOCK_sys_getrandom, buflen);
136
+ return (ssize_t)buflen;
137
+ }
138
+ }
139
+ #endif
140
+ /* There is no vsyscall. We just have to hope nobody in this test
141
+ program wants to use syscall() for anything else. */
142
+ other_syscalls = true;
143
+ fprintf (stderr, "ERROR: unexpected syscall(%ld)\n", number);
144
+ errno = ENOSYS;
145
+ return -1;
146
+ }
147
+ #endif /* HAVE_SYSCALL */
148
+
149
+ /* It is not possible to hit both of the code paths that can set the
150
+ "/dev/urandom doesn't work" flag in a single test program, because
151
+ there's no way to _clear_ that flag again. This test chooses to
152
+ exercise the read-failure path, not the open-failure path. */
153
+ #if defined HAVE_SYS_STAT_H && defined HAVE_FCNTL_H && defined HAVE_UNISTD_H
154
+ static bool urandom_should_fail = false;
155
+ static int urandom_fd = -1;
156
+ extern int __wrap_open (const char *, int, mode_t);
157
+ extern int __real_open (const char *, int, mode_t);
158
+ int
159
+ __wrap_open (const char *path, int flags, mode_t mode)
160
+ {
161
+ int ret = __real_open (path, flags, mode);
162
+ if (ret == -1)
163
+ return ret;
164
+ if (!strcmp (path, "/dev/urandom"))
165
+ urandom_fd = ret;
166
+ return ret;
167
+ }
168
+
169
+ #ifdef HAVE_OPEN64
170
+ extern int __wrap_open64 (const char *, int, mode_t);
171
+ extern int __real_open64 (const char *, int, mode_t);
172
+ int
173
+ __wrap_open64 (const char *path, int flags, mode_t mode)
174
+ {
175
+ int ret = __real_open64 (path, flags, mode);
176
+ if (ret == -1)
177
+ return ret;
178
+ if (!strcmp (path, "/dev/urandom"))
179
+ urandom_fd = ret;
180
+ return ret;
181
+ }
182
+ #endif
183
+
184
+ extern int __wrap_close (int);
185
+ extern int __real_close (int);
186
+ int
187
+ __wrap_close (int fd)
188
+ {
189
+ if (fd == urandom_fd)
190
+ urandom_fd = -1;
191
+ return __real_close (fd);
192
+ }
193
+
194
+ extern ssize_t __wrap_read (int, void *, size_t);
195
+ extern ssize_t __real_read (int, void *, size_t);
196
+ ssize_t
197
+ __wrap_read (int fd, void *buf, size_t count)
198
+ {
199
+ if (fd == urandom_fd)
200
+ {
201
+ if (urandom_should_fail)
202
+ {
203
+ errno = ENOSYS;
204
+ return -1;
205
+ }
206
+ else
207
+ {
208
+ count = MIN (count, INT16_MAX);
209
+ memset (buf, MOCK_urandom, count);
210
+ return (ssize_t)count;
211
+ }
212
+ }
213
+ else
214
+ return __real_read (fd, buf, count);
215
+ }
216
+
217
+ #endif
218
+
219
+ struct subtest
220
+ {
221
+ const char *what;
222
+ bool *make_fail;
223
+ char expected;
224
+ };
225
+ const struct subtest subtests[] =
226
+ {
227
+ { "initial", 0, 'x' },
228
+
229
+ #ifdef HAVE_GETENTROPY
230
+ { "getentropy", &getentropy_should_fail, MOCK_getentropy },
231
+ #endif
232
+ #ifdef HAVE_GETRANDOM
233
+ { "getrandom", &getrandom_should_fail, MOCK_getrandom },
234
+ #endif
235
+
236
+ #ifdef HAVE_SYSCALL
237
+ #ifdef SYS_getentropy
238
+ { "sys_getentropy", &sys_getentropy_should_fail, MOCK_sys_getentropy },
239
+ #endif
240
+ #ifdef SYS_getrandom
241
+ { "sys_getrandom", &sys_getrandom_should_fail, MOCK_sys_getrandom },
242
+ #endif
243
+ #endif
244
+
245
+ #if defined HAVE_SYS_STAT_H && defined HAVE_FCNTL_H && defined HAVE_UNISTD_H
246
+ { "/dev/urandom", &urandom_should_fail, MOCK_urandom },
247
+ #endif
248
+
249
+ { "final", 0, 0 }
250
+ };
251
+
252
+ int
253
+ main (void)
254
+ {
255
+ char buf[257];
256
+ char expected[2] = { 0, 0 };
257
+ memset (buf, 'x', sizeof buf - 1);
258
+ buf[sizeof buf - 1] = '\0';
259
+ bool failed = false;
260
+ const struct subtest *s;
261
+
262
+ for (s = subtests; s->expected;)
263
+ {
264
+ expected[0] = s->expected;
265
+ if (strspn (buf, expected) != 256)
266
+ {
267
+ printf ("FAIL: %s: buffer not filled with '%c'\n",
268
+ s->what, s->expected);
269
+ failed = true;
270
+ }
271
+ else
272
+ printf ("ok: %s (output)\n", s->what);
273
+
274
+ if (s->make_fail)
275
+ *(s->make_fail) = true;
276
+ s++;
277
+
278
+ bool r = get_random_bytes (buf, sizeof buf - 1);
279
+ buf[sizeof buf - 1] = '\0';
280
+ if ((s->expected && !r) || (!s->expected && r))
281
+ {
282
+ printf ("FAIL: %s: get_random_bytes: %s\n",
283
+ s->what, strerror (errno));
284
+ failed = true;
285
+ }
286
+ else
287
+ printf ("ok: %s (return)\n", s->what);
288
+ }
289
+ #if HAVE_SYSCALL
290
+ failed |= other_syscalls;
291
+ #endif
292
+ return failed;
293
+ }
294
+
295
+ #endif
@@ -0,0 +1,211 @@
1
+ /* Test the exposed interface of get_random_bytes.
2
+
3
+ Written by Zack Weinberg <zackw at panix.com> in 2018.
4
+ To the extent possible under law, Zack Weinberg has waived all
5
+ copyright and related or neighboring rights to this work.
6
+
7
+ See https://creativecommons.org/publicdomain/zero/1.0/ for further
8
+ details. */
9
+
10
+ #include "crypt-port.h"
11
+
12
+ #include <errno.h>
13
+ #include <setjmp.h>
14
+ #include <stdio.h>
15
+ #include <string.h>
16
+ #include <signal.h>
17
+ #include <sys/mman.h>
18
+
19
+ static bool error_occurred;
20
+
21
+ /* Note: both of the following test functions expect PAGE to point to
22
+ PAGESIZE bytes of read-write memory followed by another PAGESIZE
23
+ bytes of unwritable memory. Both functions also assume that
24
+ PAGESIZE is greater than or equal to 256. */
25
+
26
+ static void
27
+ test_basic (char *page, size_t pagesize)
28
+ {
29
+ printf ("Testing basic functionality...\n");
30
+
31
+ // A request for zero bytes should succeed, and should not touch the
32
+ // output buffer.
33
+ if (!get_random_bytes (page + pagesize, 0))
34
+ {
35
+ printf ("ERROR: get_random_bytes(0) = %s\n", strerror (errno));
36
+ error_occurred = 1;
37
+ }
38
+ else
39
+ printf ("ok: get_random_bytes(0)\n");
40
+
41
+ // A request for 257 bytes should fail, and should not touch the
42
+ // output buffer.
43
+ if (get_random_bytes (page + pagesize, 257))
44
+ {
45
+ printf ("ERROR: get_random_bytes(257) succeeded\n");
46
+ error_occurred = 1;
47
+ }
48
+ else if (errno != EIO)
49
+ {
50
+ printf ("ERROR: get_random_bytes(257) = %s (expected: %s)\n",
51
+ strerror (errno), strerror (EIO));
52
+ error_occurred = 1;
53
+ }
54
+ else
55
+ printf ("ok: get_random_bytes(257)\n");
56
+
57
+ // A request for five bytes should succeed, and should not write
58
+ // past the end of the buffer. (We use an odd, prime number here to
59
+ // catch implementations that might write e.g. four or eight bytes
60
+ // at once.)
61
+ if (!get_random_bytes (page + pagesize - 5, 5))
62
+ {
63
+ printf ("ERROR: get_random_bytes(5) = %s\n", strerror (errno));
64
+ error_occurred = 1;
65
+ }
66
+ else
67
+ printf ("ok: get_random_bytes(5)\n");
68
+
69
+ // It's extremely difficult to say whether any output of a random
70
+ // number generator is or is not "good", but the odds that 251 bytes
71
+ // of RNG output are all zero is one in 2**2008, and the odds that
72
+ // the first 251 bytes of RNG output are equal to the second 251
73
+ // bytes of RNG output is also one in 2**2008. (Again, we use an
74
+ // odd, prime number to trip up implementations that do wide writes.)
75
+
76
+ char prev[251];
77
+ memset (prev, 0, 251);
78
+
79
+ if (!get_random_bytes (page + pagesize - 251, 251))
80
+ {
81
+ printf ("ERROR: get_random_bytes(251)/1 = %s\n", strerror (errno));
82
+ error_occurred = 1;
83
+ return;
84
+ }
85
+
86
+ if (!memcmp (prev, page + pagesize - 251, 251))
87
+ {
88
+ printf ("ERROR: get_random_bytes(251)/1 produced all zeroes\n");
89
+ error_occurred = 1;
90
+ return;
91
+ }
92
+
93
+ memcpy (prev, page + pagesize - 251, 251);
94
+
95
+ if (!get_random_bytes (page + pagesize - 251, 251))
96
+ {
97
+ printf ("ERROR: get_random_bytes(251)/2 = %s\n", strerror (errno));
98
+ error_occurred = 1;
99
+ return;
100
+ }
101
+
102
+ if (!memcmp (prev, page + pagesize - 251, 251))
103
+ {
104
+ printf ("ERROR: get_random_bytes(251)/2 produced same output "
105
+ "as /1\n");
106
+ error_occurred = 1;
107
+ return;
108
+ }
109
+
110
+ printf ("ok: get_random_bytes(251) smoke test of output\n");
111
+ }
112
+
113
+ static void
114
+ test_fault (char *page, size_t pagesize)
115
+ {
116
+ printf ("Testing partially inaccessible output buffer...\n");
117
+ bool rv = get_random_bytes (page + pagesize - 64, 128);
118
+ /* shouldn't ever get here */
119
+ error_occurred = 1;
120
+ if (rv)
121
+ printf ("ERROR: success (should have faulted)\n");
122
+ else
123
+ printf ("ERROR: failed with %s (should have faulted)\n",
124
+ strerror (errno));
125
+ }
126
+
127
+ /* In one of the tests above, a segmentation fault is the expected result. */
128
+ static sigjmp_buf env;
129
+ static void
130
+ segv_handler (int sig)
131
+ {
132
+ siglongjmp (env, sig);
133
+ }
134
+
135
+ static void
136
+ expect_no_fault (char *page, size_t pagesize,
137
+ void (*testfn) (char *, size_t))
138
+ {
139
+ int rv = sigsetjmp (env, 1);
140
+ if (!rv)
141
+ testfn (page, pagesize);
142
+ else
143
+ {
144
+ printf ("ERROR: Unexpected %s\n", strsignal (rv));
145
+ error_occurred = 1;
146
+ }
147
+ }
148
+
149
+ static void
150
+ expect_a_fault (char *page, size_t pagesize,
151
+ void (*testfn) (char *, size_t))
152
+ {
153
+ int rv = sigsetjmp (env, 1);
154
+ if (!rv)
155
+ {
156
+ testfn (page, pagesize);
157
+ printf ("ERROR: No signal occurred\n");
158
+ error_occurred = 1;
159
+ }
160
+ else
161
+ {
162
+ printf ("ok: %s (as expected)\n", strsignal (rv));
163
+ }
164
+ }
165
+
166
+ int
167
+ main (void)
168
+ {
169
+ /* Set up a two-page region whose first page is read-write and
170
+ whose second page is inaccessible. */
171
+ long pagesize_l = sysconf (_SC_PAGESIZE);
172
+ if (pagesize_l < 256)
173
+ {
174
+ printf ("ERROR: pagesize of %ld is too small\n", pagesize_l);
175
+ return 99;
176
+ }
177
+
178
+ size_t pagesize = (size_t) pagesize_l;
179
+ char *page = mmap (0, pagesize * 2, PROT_READ|PROT_WRITE,
180
+ MAP_PRIVATE|MAP_ANON, -1, 0);
181
+ if (page == MAP_FAILED)
182
+ {
183
+ perror ("mmap");
184
+ return 1;
185
+ }
186
+ // coverity[overflow_sink]
187
+ memset (page, 'x', pagesize * 2);
188
+ if (mprotect (page + pagesize, pagesize, PROT_NONE))
189
+ {
190
+ perror ("mprotect");
191
+ return 1;
192
+ }
193
+
194
+ struct sigaction sa, os, ob;
195
+ sigfillset (&sa.sa_mask);
196
+ sa.sa_flags = SA_RESTART;
197
+ sa.sa_handler = segv_handler;
198
+ if (sigaction (SIGBUS, &sa, &ob) || sigaction (SIGSEGV, &sa, &os))
199
+ {
200
+ perror ("sigaction");
201
+ return 1;
202
+ }
203
+
204
+ expect_no_fault (page, pagesize, test_basic);
205
+ expect_a_fault (page, pagesize, test_fault);
206
+
207
+ sigaction (SIGBUS, &ob, 0);
208
+ sigaction (SIGSEGV, &os, 0);
209
+
210
+ return error_occurred;
211
+ }