1 /*
2  * Copyright 2021 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 <stdio.h>
11 #include <stdlib.h>
12 
13 /*
14  * Uncomment this if the fallback non-builtin overflow checking is to
15  * be tested.
16  */
17 /*#define OPENSSL_NO_BUILTIN_OVERFLOW_CHECKING*/
18 
19 #include "internal/nelem.h"
20 #include "internal/safe_math.h"
21 #include "testutil.h"
22 
23 /* Create the safe math instances we're interested in */
24 OSSL_SAFE_MATH_SIGNED(int, int)
25 OSSL_SAFE_MATH_UNSIGNED(uint, unsigned int)
26 OSSL_SAFE_MATH_UNSIGNED(size_t, size_t)
27 
28 static const struct {
29     int a, b;
30     int sum_err, sub_err, mul_err, div_err, mod_err, neg_a_err, neg_b_err;
31     int abs_a_err, abs_b_err;
32 } test_ints[] = {
33     { 1, 3,                 0, 0, 0, 0, 0, 0, 0, 0, 0 },
34     { -1, 3,                0, 0, 0, 0, 0, 0, 0, 0, 0 },
35     { 1, -3,                0, 0, 0, 0, 0, 0, 0, 0, 0 },
36     { -1, -3,               0, 0, 0, 0, 0, 0, 0, 0, 0 },
37     { INT_MAX, 1,           1, 0, 0, 0, 0, 0, 0, 0, 0 },
38     { INT_MAX, 2,           1, 0, 1, 0, 0, 0, 0, 0, 0 },
39     { INT_MIN, 1,           0, 1, 0, 0, 0, 1, 0, 1, 0 },
40     { 1, INT_MIN,           0, 1, 0, 0, 0, 0, 1, 0, 1 },
41     { INT_MIN, 2,           0, 1, 1, 0, 0, 1, 0, 1, 0 },
42     { 2, INT_MIN,           0, 1, 1, 0, 0, 0, 1, 0, 1 },
43     { INT_MIN, -1,          1, 0, 1, 1, 1, 1, 0, 1, 0 },
44     { INT_MAX, INT_MIN,     0, 1, 1, 0, 0, 0, 1, 0, 1 },
45     { INT_MIN, INT_MAX,     0, 1, 1, 0, 0, 1, 0, 1, 0 },
46     { 3, 0,                 0, 0, 0, 1, 1, 0, 0, 0, 0 },
47 };
48 
test_int_ops(int n)49 static int test_int_ops(int n)
50 {
51     int err, r;
52     const int a = test_ints[n].a, b = test_ints[n].b;
53 
54     err = 0;
55     r = safe_add_int(a, b, &err);
56     if (!TEST_int_eq(err, test_ints[n].sum_err)
57             || (!err && !TEST_int_eq(r, a + b)))
58         goto err;
59 
60     err = 0;
61     r = safe_sub_int(a, b, &err);
62     if (!TEST_int_eq(err, test_ints[n].sub_err)
63             || (!err && !TEST_int_eq(r, a - b)))
64         goto err;
65 
66     err = 0;
67     r = safe_mul_int(a, b, &err);
68     if (!TEST_int_eq(err, test_ints[n].mul_err)
69             || (!err && !TEST_int_eq(r, a * b)))
70         goto err;
71 
72     err = 0;
73     r = safe_div_int(a, b, &err);
74     if (!TEST_int_eq(err, test_ints[n].div_err)
75             || (!err && !TEST_int_eq(r, a / b)))
76         goto err;
77 
78     err = 0;
79     r = safe_mod_int(a, b, &err);
80     if (!TEST_int_eq(err, test_ints[n].mod_err)
81             || (!err && !TEST_int_eq(r, a % b)))
82         goto err;
83 
84     err = 0;
85     r = safe_neg_int(a, &err);
86     if (!TEST_int_eq(err, test_ints[n].neg_a_err)
87             || (!err && !TEST_int_eq(r, -a)))
88         goto err;
89 
90     err = 0;
91     r = safe_neg_int(b, &err);
92     if (!TEST_int_eq(err, test_ints[n].neg_b_err)
93             || (!err && !TEST_int_eq(r, -b)))
94         goto err;
95 
96     err = 0;
97     r = safe_abs_int(a, &err);
98     if (!TEST_int_eq(err, test_ints[n].abs_a_err)
99             || (!err && !TEST_int_eq(r, a < 0 ? -a : a)))
100         goto err;
101 
102     err = 0;
103     r = safe_abs_int(b, &err);
104     if (!TEST_int_eq(err, test_ints[n].abs_b_err)
105             || (!err && !TEST_int_eq(r, b < 0 ? -b : b)))
106         goto err;
107     return 1;
108  err:
109     TEST_info("a = %d  b = %d  r = %d  err = %d", a, b, r, err);
110     return 0;
111 }
112 
113 static const struct {
114     unsigned int a, b;
115     int sum_err, sub_err, mul_err, div_err, mod_err;
116 } test_uints[] = {
117     { 3, 1,                 0, 0, 0, 0, 0 },
118     { 1, 3,                 0, 1, 0, 0, 0 },
119     { UINT_MAX, 1,          1, 0, 0, 0, 0 },
120     { UINT_MAX, 2,          1, 0, 1, 0, 0 },
121     { 1, UINT_MAX,          1, 1, 0, 0, 0 },
122     { 2, UINT_MAX,          1, 1, 1, 0, 0 },
123     { UINT_MAX, 0,          0, 0, 0, 1, 1 },
124 };
125 
test_uint_ops(int n)126 static int test_uint_ops(int n)
127 {
128     int err;
129     unsigned int r;
130     const unsigned int a = test_uints[n].a, b = test_uints[n].b;
131 
132     err = 0;
133     r = safe_add_uint(a, b, &err);
134     if (!TEST_int_eq(err, test_uints[n].sum_err)
135             || (!err && !TEST_uint_eq(r, a + b)))
136         goto err;
137 
138     err = 0;
139     r = safe_sub_uint(a, b, &err);
140     if (!TEST_int_eq(err, test_uints[n].sub_err)
141             || (!err && !TEST_uint_eq(r, a - b)))
142         goto err;
143 
144     err = 0;
145     r = safe_mul_uint(a, b, &err);
146     if (!TEST_int_eq(err, test_uints[n].mul_err)
147             || (!err && !TEST_uint_eq(r, a * b)))
148         goto err;
149 
150     err = 0;
151     r = safe_div_uint(a, b, &err);
152     if (!TEST_int_eq(err, test_uints[n].div_err)
153             || (!err && !TEST_uint_eq(r, a / b)))
154         goto err;
155 
156     err = 0;
157     r = safe_mod_uint(a, b, &err);
158     if (!TEST_int_eq(err, test_uints[n].mod_err)
159             || (!err && !TEST_uint_eq(r, a % b)))
160         goto err;
161 
162     err = 0;
163     r = safe_neg_uint(a, &err);
164     if (!TEST_int_eq(err, a != 0) || (!err && !TEST_uint_eq(r, 0)))
165         goto err;
166 
167     err = 0;
168     r = safe_neg_uint(b, &err);
169     if (!TEST_int_eq(err, b != 0) || (!err && !TEST_uint_eq(r, 0)))
170         goto err;
171 
172     err = 0;
173     r = safe_abs_uint(a, &err);
174     if (!TEST_int_eq(err, 0) || !TEST_uint_eq(r, a))
175         goto err;
176 
177     err = 0;
178     r = safe_abs_uint(b, &err);
179     if (!TEST_int_eq(err, 0) || !TEST_uint_eq(r, b))
180         goto err;
181    return 1;
182  err:
183     TEST_info("a = %u  b = %u  r = %u  err = %d", a, b, r, err);
184     return 0;
185 }
186 
187 static const struct {
188     size_t a, b;
189     int sum_err, sub_err, mul_err, div_err, mod_err;
190 } test_size_ts[] = {
191     { 3, 1,                 0, 0, 0, 0, 0 },
192     { 1, 3,                 0, 1, 0, 0, 0 },
193     { SIZE_MAX, 1,          1, 0, 0, 0, 0 },
194     { SIZE_MAX, 2,          1, 0, 1, 0, 0 },
195     { 1, SIZE_MAX,          1, 1, 0, 0, 0 },
196     { 2, SIZE_MAX,          1, 1, 1, 0, 0 },
197     { 11, 0,                0, 0, 0, 1, 1 },
198 };
199 
test_size_t_ops(int n)200 static int test_size_t_ops(int n)
201 {
202     int err;
203     size_t r;
204     const size_t a = test_size_ts[n].a, b = test_size_ts[n].b;
205 
206     err = 0;
207     r = safe_add_size_t(a, b, &err);
208     if (!TEST_int_eq(err, test_size_ts[n].sum_err)
209             || (!err && !TEST_size_t_eq(r, a + b)))
210         goto err;
211 
212     err = 0;
213     r = safe_sub_size_t(a, b, &err);
214     if (!TEST_int_eq(err, test_size_ts[n].sub_err)
215             || (!err && !TEST_size_t_eq(r, a - b)))
216         goto err;
217 
218     err = 0;
219     r = safe_mul_size_t(a, b, &err);
220     if (!TEST_int_eq(err, test_size_ts[n].mul_err)
221             || (!err && !TEST_size_t_eq(r, a * b)))
222         goto err;
223 
224     err = 0;
225     r = safe_div_size_t(a, b, &err);
226     if (!TEST_int_eq(err, test_uints[n].div_err)
227             || (!err && !TEST_size_t_eq(r, a / b)))
228         goto err;
229 
230     err = 0;
231     r = safe_mod_size_t(a, b, &err);
232     if (!TEST_int_eq(err, test_size_ts[n].mod_err)
233             || (!err && !TEST_size_t_eq(r, a % b)))
234         goto err;
235 
236     err = 0;
237     r = safe_neg_size_t(a, &err);
238     if (!TEST_int_eq(err, a != 0) || (!err && !TEST_size_t_eq(r, 0)))
239         goto err;
240 
241     err = 0;
242     r = safe_neg_size_t(b, &err);
243     if (!TEST_int_eq(err, b != 0) || (!err && !TEST_size_t_eq(r, 0)))
244         goto err;
245 
246     err = 0;
247     r = safe_abs_size_t(a, &err);
248     if (!TEST_int_eq(err, 0) || !TEST_size_t_eq(r, a))
249         goto err;
250 
251     err = 0;
252     r = safe_abs_size_t(b, &err);
253     if (!TEST_int_eq(err, 0) || !TEST_size_t_eq(r, b))
254         goto err;
255     return 1;
256  err:
257     TEST_info("a = %zu  b = %zu  r = %zu  err = %d", a, b, r, err);
258     return 0;
259 }
260 
261 static const struct {
262     int a, b, c;
263     int err;
264 } test_muldiv_ints[] = {
265     { 3, 1, 2,                          0 },
266     { 1, 3, 2,                          0 },
267     { -3, 1, 2,                         0 },
268     { 1, 3, -2,                         0 },
269     { INT_MAX, INT_MAX, INT_MAX,        0 },
270     { INT_MIN, INT_MIN, INT_MAX,        1 },
271     { INT_MIN, INT_MIN, INT_MIN,        0 },
272     { INT_MAX, 2, 4,                    0 },
273     { 8, INT_MAX, 4,                    1 },
274     { INT_MAX, 8, 4,                    1 },
275     { INT_MIN, 2, 4,                    1 },
276     { 8, INT_MIN, 4,                    1 },
277     { INT_MIN, 8, 4,                    1 },
278     { 3, 4, 0,                          1 },
279 };
280 
test_int_muldiv(int n)281 static int test_int_muldiv(int n)
282 {
283     int err = 0;
284     int r, real = 0;
285     const int a = test_muldiv_ints[n].a;
286     const int b = test_muldiv_ints[n].b;
287     const int c = test_muldiv_ints[n].c;
288 
289     r = safe_muldiv_int(a, b, c, &err);
290     if (c != 0)
291         real = (int)((int64_t)a * (int64_t)b / (int64_t)c);
292     if (!TEST_int_eq(err, test_muldiv_ints[n].err)
293             || (!err && !TEST_int_eq(r, real))) {
294         TEST_info("%d * %d / %d  r = %d  err = %d", a, b, c, r, err);
295         return 0;
296     }
297     return 1;
298 }
299 
300 static const struct {
301     unsigned int a, b, c;
302     int err;
303 } test_muldiv_uints[] = {
304     { 3, 1, 2,                          0 },
305     { 1, 3, 2,                          0 },
306     { UINT_MAX, UINT_MAX, UINT_MAX,     0 },
307     { UINT_MAX, 2, 4,                   0 },
308     { 8, UINT_MAX, 4,                   1 },
309     { UINT_MAX, 8, 4,                   1 },
310     { 3, 4, 0,                          1 },
311 };
312 
test_uint_muldiv(int n)313 static int test_uint_muldiv(int n)
314 {
315     int err = 0;
316     unsigned int r, real = 0;
317     const unsigned int a = test_muldiv_uints[n].a;
318     const unsigned int b = test_muldiv_uints[n].b;
319     const unsigned int c = test_muldiv_uints[n].c;
320 
321     r = safe_muldiv_uint(a, b, c, &err);
322     if (c != 0)
323         real = (unsigned int)((uint64_t)a * (uint64_t)b / (uint64_t)c);
324     if (!TEST_int_eq(err, test_muldiv_uints[n].err)
325             || (!err && !TEST_uint_eq(r, real))) {
326         TEST_info("%u * %u / %u  r = %u  err = %d", a, b, c, r, err);
327         return 0;
328     }
329     return 1;
330 }
331 
setup_tests(void)332 int setup_tests(void)
333 {
334     ADD_ALL_TESTS(test_int_ops, OSSL_NELEM(test_ints));
335     ADD_ALL_TESTS(test_uint_ops, OSSL_NELEM(test_uints));
336     ADD_ALL_TESTS(test_size_t_ops, OSSL_NELEM(test_size_ts));
337     ADD_ALL_TESTS(test_int_muldiv, OSSL_NELEM(test_muldiv_ints));
338     ADD_ALL_TESTS(test_uint_muldiv, OSSL_NELEM(test_muldiv_uints));
339     return 1;
340 }
341