master
c 271 lines 6.39 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 random.c
8
9 Abstract:
10
11 This file is a test for the getrandom system call and the /dev/random and
12 /dev/urandom devices.
13
14 --*/
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <sys/socket.h>
24 #include <sys/un.h>
25 #include <netinet/in.h>
26 #include <netdb.h>
27 #include <time.h>
28 #include <linux/random.h>
29 #include "lxtcommon.h"
30 #include "unittests.h"
31
32 #define DEV_RANDOM "/dev/random"
33 #define DEV_RANDOM_MAX_BYTES (512)
34
35 #define DEV_URANDOM "/dev/urandom"
36 #define DEV_URANDOM_MAX_BYTES (0x1FFFFFF)
37
38 #define PROC_SYS_KERNEL_RANDOM "/proc/sys/kernel/random"
39 #define PROC_SYS_KERNEL_RANDOM_BOOTID PROC_SYS_KERNEL_RANDOM "/boot_id"
40 #define PROC_SYS_KERNEL_RANDOM_ENTROPY_AVAIL PROC_SYS_KERNEL_RANDOM "/entropy_avail"
41 #define PROC_SYS_KERNEL_RANDOM_POOLSIZE PROC_SYS_KERNEL_RANDOM "/poolsize"
42 #define PROC_SYS_KERNEL_RANDOM_UUID PROC_SYS_KERNEL_RANDOM "/uuid"
43 #define PROC_SYS_KERNEL_RANDOM_BYTES 37
44
45 #define LXT_NAME "random"
46
47 int GetrandomSyscall(PLXT_ARGS Args);
48
49 int DevRandomDevice(PLXT_ARGS Args);
50
51 int DevUrandomDevice(PLXT_ARGS Args);
52
53 int ProcfsRandom(PLXT_ARGS Args);
54
55 static const LXT_VARIATION g_LxtVariations[] = {
56 {"getrandom syscall", GetrandomSyscall},
57 {"/dev/random device", DevRandomDevice},
58 {"/dev/urandom device", DevUrandomDevice},
59 {"/proc/sys/kernel/random", ProcfsRandom}};
60
61 int RandomTestEntry(int Argc, char* Argv[])
62 {
63
64 LXT_ARGS Args;
65 int Result;
66
67 LxtCheckResult(LxtInitialize(Argc, Argv, &Args, LXT_NAME));
68 LxtCheckResult(LxtRunVariations(&Args, g_LxtVariations, LXT_COUNT_OF(g_LxtVariations)));
69
70 ErrorExit:
71 LxtUninitialize();
72 return 0;
73 }
74
75 int GetrandomSyscall(PLXT_ARGS Args)
76
77 {
78
79 char* Buffer;
80 size_t BufferSize;
81 size_t Result;
82
83 BufferSize = DEV_URANDOM_MAX_BYTES + 1;
84 Buffer = malloc(BufferSize);
85 if (Buffer == NULL)
86 {
87 Result = LXT_RESULT_FAILURE;
88 LxtLogError("malloc failed");
89 goto ErrorExit;
90 }
91
92 //
93 // Valid parameter variations.
94 //
95
96 LxtCheckResult(LxtGetrandom(NULL, 0, 0));
97 LxtCheckEqual(Result, 0, "%Iu");
98 LxtCheckResult(LxtGetrandom(NULL, 0, GRND_RANDOM));
99 LxtCheckResult(LxtGetrandom(NULL, 0, GRND_NONBLOCK));
100 LxtCheckResult(LxtGetrandom(NULL, 0, (GRND_RANDOM | GRND_NONBLOCK)));
101 LxtCheckResult(LxtGetrandom(Buffer, BufferSize, 0));
102 if (Result > DEV_URANDOM_MAX_BYTES)
103 {
104 Result = LXT_RESULT_FAILURE;
105 LxtLogError("BytesRead %Iu greater than expected %Iu", Result, DEV_URANDOM_MAX_BYTES);
106
107 goto ErrorExit;
108 }
109
110 LxtCheckResult(LxtGetrandom(Buffer, BufferSize, GRND_RANDOM));
111 if (Result > DEV_RANDOM_MAX_BYTES)
112 {
113 Result = LXT_RESULT_FAILURE;
114 LxtLogError("BytesRead %Iu greater than expected %Iu", Result, DEV_RANDOM_MAX_BYTES);
115
116 goto ErrorExit;
117 }
118
119 //
120 // Invalid parameter variations.
121 //
122
123 LxtCheckErrnoFailure(LxtGetrandom(NULL, 0, ((GRND_RANDOM | GRND_NONBLOCK) + 1)), EINVAL);
124 LxtCheckErrnoFailure(LxtGetrandom(NULL, 0, -1), EINVAL);
125 LxtCheckErrnoFailure(LxtGetrandom(NULL, 1, 0), EFAULT);
126 LxtCheckErrnoFailure(LxtGetrandom(-1, 1, 0), EFAULT);
127
128 ErrorExit:
129 if (Buffer != NULL)
130 {
131 free(Buffer);
132 }
133
134 return Result;
135 }
136
137 int DevRandomDevice(PLXT_ARGS Args)
138 {
139
140 char Buffer[DEV_RANDOM_MAX_BYTES + 1];
141 int BytesRead;
142 int Fd;
143 int Result;
144
145 Fd = -1;
146
147 LxtCheckResult(Fd = open(DEV_RANDOM, O_RDONLY));
148 LxtCheckResult(BytesRead = read(Fd, Buffer, LXT_COUNT_OF(Buffer)));
149
150 if (BytesRead > DEV_RANDOM_MAX_BYTES)
151 {
152 Result = LXT_RESULT_FAILURE;
153 LxtLogError("BytesRead %d greater than expected %d", BytesRead, DEV_RANDOM_MAX_BYTES);
154
155 goto ErrorExit;
156 }
157
158 Result = LXT_RESULT_SUCCESS;
159
160 ErrorExit:
161 if (Fd != -1)
162 {
163 LxtClose(Fd);
164 }
165
166 return Result;
167 }
168
169 int DevUrandomDevice(PLXT_ARGS Args)
170 {
171
172 char* Buffer;
173 size_t BufferSize;
174 int BytesRead;
175 int Fd;
176 int Result;
177
178 BufferSize = DEV_URANDOM_MAX_BYTES + 1;
179 Fd = -1;
180 Buffer = malloc(BufferSize);
181 if (Buffer == NULL)
182 {
183 Result = LXT_RESULT_FAILURE;
184 LxtLogError("malloc failed");
185 goto ErrorExit;
186 }
187
188 LxtCheckResult(Fd = open(DEV_URANDOM, O_RDONLY));
189 LxtCheckResult(BytesRead = read(Fd, Buffer, BufferSize));
190 if (BytesRead > DEV_URANDOM_MAX_BYTES)
191 {
192 Result = LXT_RESULT_FAILURE;
193 LxtLogError("BytesRead %d greater than expected %d", BytesRead, DEV_URANDOM_MAX_BYTES);
194
195 goto ErrorExit;
196 }
197
198 Result = LXT_RESULT_SUCCESS;
199
200 ErrorExit:
201 if (Buffer != NULL)
202 {
203 free(Buffer);
204 }
205
206 if (Fd != -1)
207 {
208 LxtClose(Fd);
209 }
210
211 return Result;
212 }
213
214 int ProcfsRandom(PLXT_ARGS Args)
215
216 {
217 char Buffer[PROC_SYS_KERNEL_RANDOM_BYTES];
218 int BytesRead;
219 int Fd;
220 int Result;
221
222 //
223 // Test /proc/sys/kernel/random/uuid.
224 //
225
226 LxtCheckResult(Fd = open(PROC_SYS_KERNEL_RANDOM_UUID, O_RDONLY));
227 LxtCheckResult(BytesRead = read(Fd, Buffer, sizeof(Buffer)));
228 LxtCheckEqual(PROC_SYS_KERNEL_RANDOM_BYTES, BytesRead, "%d");
229 LxtClose(Fd);
230 Fd = -1;
231
232 //
233 // Test /proc/sys/kernel/random/boot_id.
234 //
235
236 LxtCheckResult(Fd = open(PROC_SYS_KERNEL_RANDOM_BOOTID, O_RDONLY));
237 LxtCheckResult(BytesRead = read(Fd, Buffer, sizeof(Buffer)));
238 LxtCheckEqual(PROC_SYS_KERNEL_RANDOM_BYTES, BytesRead, "%d");
239 LxtClose(Fd);
240 Fd = -1;
241
242 //
243 // Test /proc/sys/kernel/random/entropy_avail.
244 //
245
246 LxtCheckResult(Fd = open(PROC_SYS_KERNEL_RANDOM_ENTROPY_AVAIL, O_RDONLY));
247 LxtCheckResult(BytesRead = read(Fd, Buffer, (sizeof(Buffer) - 1)));
248 LxtCheckEqual(5, BytesRead, "%d");
249 LxtClose(Fd);
250 Fd = -1;
251
252 //
253 // Test /proc/sys/kernel/random/poolsize.
254 //
255
256 LxtCheckResult(Fd = open(PROC_SYS_KERNEL_RANDOM_POOLSIZE, O_RDONLY));
257 LxtCheckResult(BytesRead = read(Fd, Buffer, (sizeof(Buffer) - 1)));
258 LxtCheckEqual(5, BytesRead, "%d");
259 Buffer[BytesRead] = '\0';
260 LxtCheckStringEqual(Buffer, "4096\n");
261 LxtClose(Fd);
262 Fd = -1;
263
264 ErrorExit:
265 if (Fd != -1)
266 {
267 LxtClose(Fd);
268 }
269
270 return Result;
271 }