]>
git.ipfire.org Git - thirdparty/openssl.git/blob - test/safe_math_test.c
2 * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved.
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
14 * Uncomment this if the fallback non-builtin overflow checking is to
17 /*#define OPENSSL_NO_BUILTIN_OVERFLOW_CHECKING*/
19 #include "internal/nelem.h"
20 #include "internal/safe_math.h"
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)
30 int sum_err
, sub_err
, mul_err
, div_err
, mod_err
, div_round_up_err
;
31 int neg_a_err
, neg_b_err
, abs_a_err
, abs_b_err
;
32 } test_ints
[] = { /* + - * / % /r -a -b |a||b| */
33 { 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
34 { -1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
35 { 1, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
36 { -1, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
37 { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
38 { -3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
39 { 2, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
40 { -2, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
41 { INT_MAX
, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
42 { INT_MAX
, 2, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
43 { INT_MAX
, 4, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
44 { INT_MAX
- 3 , 4, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
45 { INT_MIN
, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0 },
46 { 1, INT_MIN
, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1 },
47 { INT_MIN
, 2, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0 },
48 { 2, INT_MIN
, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1 },
49 { INT_MIN
, -1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0 },
50 { INT_MAX
, INT_MIN
, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1 },
51 { INT_MIN
, INT_MAX
, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0 },
52 { 3, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 },
55 static int test_int_ops(int n
)
58 const int a
= test_ints
[n
].a
, b
= test_ints
[n
].b
;
61 r
= safe_add_int(a
, b
, &err
);
62 if (!TEST_int_eq(err
, test_ints
[n
].sum_err
)
63 || (!err
&& !TEST_int_eq(r
, a
+ b
)))
67 r
= safe_sub_int(a
, b
, &err
);
68 if (!TEST_int_eq(err
, test_ints
[n
].sub_err
)
69 || (!err
&& !TEST_int_eq(r
, a
- b
)))
73 r
= safe_mul_int(a
, b
, &err
);
74 if (!TEST_int_eq(err
, test_ints
[n
].mul_err
)
75 || (!err
&& !TEST_int_eq(r
, a
* b
)))
79 r
= safe_div_int(a
, b
, &err
);
80 if (!TEST_int_eq(err
, test_ints
[n
].div_err
)
81 || (!err
&& !TEST_int_eq(r
, a
/ b
)))
85 r
= safe_mod_int(a
, b
, &err
);
86 if (!TEST_int_eq(err
, test_ints
[n
].mod_err
)
87 || (!err
&& !TEST_int_eq(r
, a
% b
)))
91 r
= safe_div_round_up_int(a
, b
, &err
);
92 if (!TEST_int_eq(err
, test_ints
[n
].div_round_up_err
))
94 s
= safe_mod_int(a
, b
, &err
);
95 s
= safe_add_int(safe_div_int(a
, b
, &err
), s
!= 0, &err
);
96 if (!err
&& !TEST_int_eq(r
, s
))
100 r
= safe_neg_int(a
, &err
);
101 if (!TEST_int_eq(err
, test_ints
[n
].neg_a_err
)
102 || (!err
&& !TEST_int_eq(r
, -a
)))
106 r
= safe_neg_int(b
, &err
);
107 if (!TEST_int_eq(err
, test_ints
[n
].neg_b_err
)
108 || (!err
&& !TEST_int_eq(r
, -b
)))
112 r
= safe_abs_int(a
, &err
);
113 if (!TEST_int_eq(err
, test_ints
[n
].abs_a_err
)
114 || (!err
&& !TEST_int_eq(r
, a
< 0 ? -a
: a
)))
118 r
= safe_abs_int(b
, &err
);
119 if (!TEST_int_eq(err
, test_ints
[n
].abs_b_err
)
120 || (!err
&& !TEST_int_eq(r
, b
< 0 ? -b
: b
)))
124 TEST_info("a = %d b = %d r = %d err = %d", a
, b
, r
, err
);
128 static const struct {
130 int sum_err
, sub_err
, mul_err
, div_err
, mod_err
, div_round_up_err
;
131 } test_uints
[] = { /* + - * / % /r */
132 { 3, 1, 0, 0, 0, 0, 0, 0 },
133 { 1, 3, 0, 1, 0, 0, 0, 0 },
134 { UINT_MAX
, 1, 1, 0, 0, 0, 0, 0 },
135 { UINT_MAX
, 2, 1, 0, 1, 0, 0, 0 },
136 { UINT_MAX
, 16, 1, 0, 1, 0, 0, 0 },
137 { UINT_MAX
- 13, 16, 1, 0, 1, 0, 0, 0 },
138 { 1, UINT_MAX
, 1, 1, 0, 0, 0, 0 },
139 { 2, UINT_MAX
, 1, 1, 1, 0, 0, 0 },
140 { UINT_MAX
, 0, 0, 0, 0, 1, 1, 1 },
143 static int test_uint_ops(int n
)
147 const unsigned int a
= test_uints
[n
].a
, b
= test_uints
[n
].b
;
150 r
= safe_add_uint(a
, b
, &err
);
151 if (!TEST_int_eq(err
, test_uints
[n
].sum_err
)
152 || (!err
&& !TEST_uint_eq(r
, a
+ b
)))
156 r
= safe_sub_uint(a
, b
, &err
);
157 if (!TEST_int_eq(err
, test_uints
[n
].sub_err
)
158 || (!err
&& !TEST_uint_eq(r
, a
- b
)))
162 r
= safe_mul_uint(a
, b
, &err
);
163 if (!TEST_int_eq(err
, test_uints
[n
].mul_err
)
164 || (!err
&& !TEST_uint_eq(r
, a
* b
)))
168 r
= safe_div_uint(a
, b
, &err
);
169 if (!TEST_int_eq(err
, test_uints
[n
].div_err
)
170 || (!err
&& !TEST_uint_eq(r
, a
/ b
)))
174 r
= safe_mod_uint(a
, b
, &err
);
175 if (!TEST_int_eq(err
, test_uints
[n
].mod_err
)
176 || (!err
&& !TEST_uint_eq(r
, a
% b
)))
180 r
= safe_div_round_up_uint(a
, b
, &err
);
181 if (!TEST_int_eq(err
, test_uints
[n
].div_round_up_err
)
182 || (!err
&& !TEST_uint_eq(r
, a
/ b
+ (a
% b
!= 0))))
186 r
= safe_neg_uint(a
, &err
);
187 if (!TEST_int_eq(err
, a
!= 0) || (!err
&& !TEST_uint_eq(r
, 0)))
191 r
= safe_neg_uint(b
, &err
);
192 if (!TEST_int_eq(err
, b
!= 0) || (!err
&& !TEST_uint_eq(r
, 0)))
196 r
= safe_abs_uint(a
, &err
);
197 if (!TEST_int_eq(err
, 0) || !TEST_uint_eq(r
, a
))
201 r
= safe_abs_uint(b
, &err
);
202 if (!TEST_int_eq(err
, 0) || !TEST_uint_eq(r
, b
))
206 TEST_info("a = %u b = %u r = %u err = %d", a
, b
, r
, err
);
210 static const struct {
212 int sum_err
, sub_err
, mul_err
, div_err
, mod_err
, div_round_up_err
;
214 { 3, 1, 0, 0, 0, 0, 0, 0 },
215 { 1, 3, 0, 1, 0, 0, 0, 0 },
216 { 36, 8, 0, 0, 0, 0, 0, 0 },
217 { SIZE_MAX
, 1, 1, 0, 0, 0, 0, 0 },
218 { SIZE_MAX
, 2, 1, 0, 1, 0, 0, 0 },
219 { SIZE_MAX
, 8, 1, 0, 1, 0, 0, 0 },
220 { SIZE_MAX
- 3, 8, 1, 0, 1, 0, 0, 0 },
221 { 1, SIZE_MAX
, 1, 1, 0, 0, 0, 0 },
222 { 2, SIZE_MAX
, 1, 1, 1, 0, 0, 0 },
223 { 11, 0, 0, 0, 0, 1, 1, 1 },
226 static int test_size_t_ops(int n
)
230 const size_t a
= test_size_ts
[n
].a
, b
= test_size_ts
[n
].b
;
233 r
= safe_add_size_t(a
, b
, &err
);
234 if (!TEST_int_eq(err
, test_size_ts
[n
].sum_err
)
235 || (!err
&& !TEST_size_t_eq(r
, a
+ b
)))
239 r
= safe_sub_size_t(a
, b
, &err
);
240 if (!TEST_int_eq(err
, test_size_ts
[n
].sub_err
)
241 || (!err
&& !TEST_size_t_eq(r
, a
- b
)))
245 r
= safe_mul_size_t(a
, b
, &err
);
246 if (!TEST_int_eq(err
, test_size_ts
[n
].mul_err
)
247 || (!err
&& !TEST_size_t_eq(r
, a
* b
)))
251 r
= safe_div_size_t(a
, b
, &err
);
252 if (!TEST_int_eq(err
, test_size_ts
[n
].div_err
)
253 || (!err
&& !TEST_size_t_eq(r
, a
/ b
)))
257 r
= safe_mod_size_t(a
, b
, &err
);
258 if (!TEST_int_eq(err
, test_size_ts
[n
].mod_err
)
259 || (!err
&& !TEST_size_t_eq(r
, a
% b
)))
263 r
= safe_div_round_up_size_t(a
, b
, &err
);
264 if (!TEST_int_eq(err
, test_size_ts
[n
].div_round_up_err
)
265 || (!err
&& !TEST_size_t_eq(r
, a
/ b
+ (a
% b
!= 0))))
269 r
= safe_neg_size_t(a
, &err
);
270 if (!TEST_int_eq(err
, a
!= 0) || (!err
&& !TEST_size_t_eq(r
, 0)))
274 r
= safe_neg_size_t(b
, &err
);
275 if (!TEST_int_eq(err
, b
!= 0) || (!err
&& !TEST_size_t_eq(r
, 0)))
279 r
= safe_abs_size_t(a
, &err
);
280 if (!TEST_int_eq(err
, 0) || !TEST_size_t_eq(r
, a
))
284 r
= safe_abs_size_t(b
, &err
);
285 if (!TEST_int_eq(err
, 0) || !TEST_size_t_eq(r
, b
))
289 TEST_info("a = %zu b = %zu r = %zu err = %d", a
, b
, r
, err
);
293 static const struct {
296 } test_muldiv_ints
[] = {
301 { INT_MAX
, INT_MAX
, INT_MAX
, 0 },
302 { INT_MIN
, INT_MIN
, INT_MAX
, 1 },
303 { INT_MIN
, INT_MIN
, INT_MIN
, 0 },
304 { INT_MAX
, 2, 4, 0 },
305 { 8, INT_MAX
, 4, 1 },
306 { INT_MAX
, 8, 4, 1 },
307 { INT_MIN
, 2, 4, 1 },
308 { 8, INT_MIN
, 4, 1 },
309 { INT_MIN
, 8, 4, 1 },
313 static int test_int_muldiv(int n
)
317 const int a
= test_muldiv_ints
[n
].a
;
318 const int b
= test_muldiv_ints
[n
].b
;
319 const int c
= test_muldiv_ints
[n
].c
;
321 r
= safe_muldiv_int(a
, b
, c
, &err
);
323 real
= (int)((int64_t)a
* (int64_t)b
/ (int64_t)c
);
324 if (!TEST_int_eq(err
, test_muldiv_ints
[n
].err
)
325 || (!err
&& !TEST_int_eq(r
, real
))) {
326 TEST_info("%d * %d / %d r = %d err = %d", a
, b
, c
, r
, err
);
332 static const struct {
333 unsigned int a
, b
, c
;
335 } test_muldiv_uints
[] = {
338 { UINT_MAX
, UINT_MAX
, UINT_MAX
, 0 },
339 { UINT_MAX
, 2, 4, 0 },
340 { 8, UINT_MAX
, 4, 1 },
341 { UINT_MAX
, 8, 4, 1 },
345 static int test_uint_muldiv(int n
)
348 unsigned int r
, real
= 0;
349 const unsigned int a
= test_muldiv_uints
[n
].a
;
350 const unsigned int b
= test_muldiv_uints
[n
].b
;
351 const unsigned int c
= test_muldiv_uints
[n
].c
;
353 r
= safe_muldiv_uint(a
, b
, c
, &err
);
355 real
= (unsigned int)((uint64_t)a
* (uint64_t)b
/ (uint64_t)c
);
356 if (!TEST_int_eq(err
, test_muldiv_uints
[n
].err
)
357 || (!err
&& !TEST_uint_eq(r
, real
))) {
358 TEST_info("%u * %u / %u r = %u err = %d", a
, b
, c
, r
, err
);
364 int setup_tests(void)
366 ADD_ALL_TESTS(test_int_ops
, OSSL_NELEM(test_ints
));
367 ADD_ALL_TESTS(test_uint_ops
, OSSL_NELEM(test_uints
));
368 ADD_ALL_TESTS(test_size_t_ops
, OSSL_NELEM(test_size_ts
));
369 ADD_ALL_TESTS(test_int_muldiv
, OSSL_NELEM(test_muldiv_ints
));
370 ADD_ALL_TESTS(test_uint_muldiv
, OSSL_NELEM(test_muldiv_uints
));