xref: /freebsd/crypto/openssl/test/sanitytest.c (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
1 /*
2  * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <string.h>
11 #include <openssl/types.h>
12 #include "testutil.h"
13 #include "internal/numbers.h"
14 #include "internal/time.h"
15 
16 #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L
17 #include <signal.h>
18 #endif
19 
test_sanity_null_zero(void)20 static int test_sanity_null_zero(void)
21 {
22     char *p;
23     char bytes[sizeof(p)];
24 
25     /* Is NULL equivalent to all-bytes-zero? */
26     p = NULL;
27     memset(bytes, 0, sizeof(bytes));
28     return TEST_mem_eq(&p, sizeof(p), bytes, sizeof(bytes));
29 }
30 
test_sanity_enum_size(void)31 static int test_sanity_enum_size(void)
32 {
33     enum smallchoices { sa,
34         sb,
35         sc };
36     enum medchoices { ma,
37         mb,
38         mc,
39         md,
40         me,
41         mf,
42         mg,
43         mh,
44         mi,
45         mj,
46         mk,
47         ml };
48     enum largechoices {
49         a01,
50         b01,
51         c01,
52         d01,
53         e01,
54         f01,
55         g01,
56         h01,
57         i01,
58         j01,
59         a02,
60         b02,
61         c02,
62         d02,
63         e02,
64         f02,
65         g02,
66         h02,
67         i02,
68         j02,
69         a03,
70         b03,
71         c03,
72         d03,
73         e03,
74         f03,
75         g03,
76         h03,
77         i03,
78         j03,
79         a04,
80         b04,
81         c04,
82         d04,
83         e04,
84         f04,
85         g04,
86         h04,
87         i04,
88         j04,
89         a05,
90         b05,
91         c05,
92         d05,
93         e05,
94         f05,
95         g05,
96         h05,
97         i05,
98         j05,
99         a06,
100         b06,
101         c06,
102         d06,
103         e06,
104         f06,
105         g06,
106         h06,
107         i06,
108         j06,
109         a07,
110         b07,
111         c07,
112         d07,
113         e07,
114         f07,
115         g07,
116         h07,
117         i07,
118         j07,
119         a08,
120         b08,
121         c08,
122         d08,
123         e08,
124         f08,
125         g08,
126         h08,
127         i08,
128         j08,
129         a09,
130         b09,
131         c09,
132         d09,
133         e09,
134         f09,
135         g09,
136         h09,
137         i09,
138         j09,
139         a10,
140         b10,
141         c10,
142         d10,
143         e10,
144         f10,
145         g10,
146         h10,
147         i10,
148         j10,
149         xxx
150     };
151 
152     /* Enum size */
153     if (!TEST_size_t_eq(sizeof(enum smallchoices), sizeof(int))
154         || !TEST_size_t_eq(sizeof(enum medchoices), sizeof(int))
155         || !TEST_size_t_eq(sizeof(enum largechoices), sizeof(int)))
156         return 0;
157     return 1;
158 }
159 
test_sanity_twos_complement(void)160 static int test_sanity_twos_complement(void)
161 {
162     /* Basic two's complement checks. */
163     if (!TEST_int_eq(~(-1), 0)
164         || !TEST_long_eq(~(-1L), 0L))
165         return 0;
166     return 1;
167 }
168 
test_sanity_sign(void)169 static int test_sanity_sign(void)
170 {
171     /* Check that values with sign bit 1 and value bits 0 are valid */
172     if (!TEST_int_eq(-(INT_MIN + 1), INT_MAX)
173         || !TEST_long_eq(-(LONG_MIN + 1), LONG_MAX))
174         return 0;
175     return 1;
176 }
177 
test_sanity_unsigned_conversion(void)178 static int test_sanity_unsigned_conversion(void)
179 {
180     /* Check that unsigned-to-signed conversions preserve bit patterns */
181     if (!TEST_int_eq((int)((unsigned int)INT_MAX + 1), INT_MIN)
182         || !TEST_long_eq((long)((unsigned long)LONG_MAX + 1), LONG_MIN))
183         return 0;
184     return 1;
185 }
186 
test_sanity_range(void)187 static int test_sanity_range(void)
188 {
189     /* Verify some types are the correct size */
190     if (!TEST_size_t_eq(sizeof(int8_t), 1)
191         || !TEST_size_t_eq(sizeof(uint8_t), 1)
192         || !TEST_size_t_eq(sizeof(int16_t), 2)
193         || !TEST_size_t_eq(sizeof(uint16_t), 2)
194         || !TEST_size_t_eq(sizeof(int32_t), 4)
195         || !TEST_size_t_eq(sizeof(uint32_t), 4)
196         || !TEST_size_t_eq(sizeof(int64_t), 8)
197         || !TEST_size_t_eq(sizeof(uint64_t), 8)
198 #ifdef UINT128_MAX
199         || !TEST_size_t_eq(sizeof(int128_t), 16)
200         || !TEST_size_t_eq(sizeof(uint128_t), 16)
201 #endif
202         || !TEST_size_t_eq(sizeof(char), 1)
203         || !TEST_size_t_eq(sizeof(unsigned char), 1))
204         return 0;
205 
206     /* We want our long longs to be at least 64 bits */
207     if (!TEST_size_t_ge(sizeof(long long int), 8)
208         || !TEST_size_t_ge(sizeof(unsigned long long int), 8))
209         return 0;
210 
211     /*
212      * Verify intmax_t.
213      * Some platforms defined intmax_t to be 64 bits but still support
214      * an int128_t, so this check is for at least 64 bits.
215      */
216     if (!TEST_size_t_ge(sizeof(ossl_intmax_t), 8)
217         || !TEST_size_t_ge(sizeof(ossl_uintmax_t), 8)
218         || !TEST_size_t_ge(sizeof(ossl_uintmax_t), sizeof(size_t)))
219         return 0;
220 
221     /* This isn't possible to check using the framework functions */
222     if (SIZE_MAX < INT_MAX) {
223         TEST_error("int must not be wider than size_t");
224         return 0;
225     }
226 
227     /* SIZE_MAX is always greater than 2*INT_MAX */
228     if (SIZE_MAX - INT_MAX <= INT_MAX) {
229         TEST_error("SIZE_MAX must exceed 2*INT_MAX");
230         return 0;
231     }
232 
233     return 1;
234 }
235 
test_sanity_memcmp(void)236 static int test_sanity_memcmp(void)
237 {
238     return CRYPTO_memcmp("ab", "cd", 2);
239 }
240 
241 static const struct sleep_test_vector {
242     uint64_t val;
243 } sleep_test_vectors[] = { { 0 }, { 1 }, { 999 }, { 1000 } };
244 
245 #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L
246 static void
alrm_handler(int sig)247 alrm_handler(int sig)
248 {
249 }
250 #endif /* defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L */
251 
test_sanity_sleep(int i)252 static int test_sanity_sleep(int i)
253 {
254     const struct sleep_test_vector *const td = sleep_test_vectors + i;
255     OSSL_TIME start = ossl_time_now();
256     uint64_t ms;
257 
258 #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L
259     /*
260      * Set up an interrupt timer to check that OSSL_sleep doesn't return early
261      * due to interrupts.
262      */
263     do {
264         static const struct itimerval it = { { 0, 111111 } };
265         struct sigaction sa;
266         sigset_t mask;
267 
268         memset(&sa, 0, sizeof(sa));
269         sa.sa_handler = alrm_handler;
270 
271         if (sigaction(SIGALRM, &sa, NULL)) {
272             TEST_perror("test_sanity_sleep: sigaction");
273             break;
274         }
275 
276         sigemptyset(&mask);
277         sigaddset(&mask, SIGALRM);
278         if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
279             TEST_perror("test_sanity_sleep: sigprocmask");
280             break;
281         }
282 
283         if (setitimer(ITIMER_REAL, &it, NULL)) {
284             TEST_perror("test_sanity_sleep: arm setitimer");
285             break;
286         }
287     } while (0);
288 #endif /* defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L */
289 
290     /*
291      * On any reasonable system this must sleep at least the specified time
292      * but not more than 20 seconds more than that.
293      */
294     OSSL_sleep(td->val);
295 
296 #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L
297     /* disarm the timer */
298     do {
299         static const struct itimerval it;
300 
301         if (setitimer(ITIMER_REAL, &it, NULL)) {
302             TEST_perror("test_sanity_sleep: disarm setitimer");
303             break;
304         }
305     } while (0);
306 #endif /* defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L */
307 
308     ms = ossl_time2ms(ossl_time_subtract(ossl_time_now(), start));
309 
310     if (!TEST_uint64_t_ge(ms, td->val) + !TEST_uint64_t_le(ms, td->val + 20000))
311         return 0;
312     return 1;
313 }
314 
setup_tests(void)315 int setup_tests(void)
316 {
317     ADD_TEST(test_sanity_null_zero);
318     ADD_TEST(test_sanity_enum_size);
319     ADD_TEST(test_sanity_twos_complement);
320     ADD_TEST(test_sanity_sign);
321     ADD_TEST(test_sanity_unsigned_conversion);
322     ADD_TEST(test_sanity_range);
323     ADD_TEST(test_sanity_memcmp);
324     ADD_ALL_TESTS(test_sanity_sleep, OSSL_NELEM(sleep_test_vectors));
325     return 1;
326 }
327