| 
									
										
										
										
											2021-10-28 07:21:40 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2022-05-03 18:52:38 +08:00
										 |  |  |  * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2021-10-28 07:21:40 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
					
						
							|  |  |  |  * this file except in compliance with the License.  You can obtain a copy | 
					
						
							|  |  |  |  * in the file LICENSE in the source distribution or at | 
					
						
							|  |  |  |  * https://www.openssl.org/source/license.html
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Uncomment this if the fallback non-builtin overflow checking is to | 
					
						
							|  |  |  |  * be tested. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | /*#define OPENSSL_NO_BUILTIN_OVERFLOW_CHECKING*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "internal/nelem.h"
 | 
					
						
							|  |  |  | #include "internal/safe_math.h"
 | 
					
						
							|  |  |  | #include "testutil.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Create the safe math instances we're interested in */ | 
					
						
							|  |  |  | OSSL_SAFE_MATH_SIGNED(int, int) | 
					
						
							|  |  |  | OSSL_SAFE_MATH_UNSIGNED(uint, unsigned int) | 
					
						
							|  |  |  | OSSL_SAFE_MATH_UNSIGNED(size_t, size_t) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const struct { | 
					
						
							|  |  |  |     int a, b; | 
					
						
							| 
									
										
										
										
											2022-03-15 11:19:07 +08:00
										 |  |  |     int sum_err, sub_err, mul_err, div_err, mod_err, div_round_up_err; | 
					
						
							|  |  |  |     int neg_a_err, neg_b_err, abs_a_err, abs_b_err; | 
					
						
							|  |  |  | } test_ints[] = {       /*  +  -  *  /  %  /r -a -b |a||b|  */ | 
					
						
							|  |  |  |     { 1, 3,                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { -1, 3,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { 1, -3,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { -1, -3,               0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { 3, 2,                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { -3, 2,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { 2, -3,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { -2, -3,               0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { INT_MAX, 1,           1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { INT_MAX, 2,           1, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { INT_MAX, 4,           1, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { INT_MAX - 3 , 4,      1, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { INT_MIN, 1,           0, 1, 0, 0, 0, 0, 1, 0, 1, 0 }, | 
					
						
							|  |  |  |     { 1, INT_MIN,           0, 1, 0, 0, 0, 0, 0, 1, 0, 1 }, | 
					
						
							|  |  |  |     { INT_MIN, 2,           0, 1, 1, 0, 0, 0, 1, 0, 1, 0 }, | 
					
						
							|  |  |  |     { 2, INT_MIN,           0, 1, 1, 0, 0, 0, 0, 1, 0, 1 }, | 
					
						
							|  |  |  |     { INT_MIN, -1,          1, 0, 1, 1, 1, 1, 1, 0, 1, 0 }, | 
					
						
							|  |  |  |     { INT_MAX, INT_MIN,     0, 1, 1, 0, 0, 0, 0, 1, 0, 1 }, | 
					
						
							|  |  |  |     { INT_MIN, INT_MAX,     0, 1, 1, 0, 0, 0, 1, 0, 1, 0 }, | 
					
						
							|  |  |  |     { 3, 0,                 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 }, | 
					
						
							| 
									
										
										
										
											2021-10-28 07:21:40 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int test_int_ops(int n) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-03-15 11:19:07 +08:00
										 |  |  |     int err, r, s; | 
					
						
							| 
									
										
										
										
											2021-10-28 07:21:40 +08:00
										 |  |  |     const int a = test_ints[n].a, b = test_ints[n].b; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_add_int(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_ints[n].sum_err) | 
					
						
							|  |  |  |             || (!err && !TEST_int_eq(r, a + b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_sub_int(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_ints[n].sub_err) | 
					
						
							|  |  |  |             || (!err && !TEST_int_eq(r, a - b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_mul_int(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_ints[n].mul_err) | 
					
						
							|  |  |  |             || (!err && !TEST_int_eq(r, a * b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_div_int(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_ints[n].div_err) | 
					
						
							|  |  |  |             || (!err && !TEST_int_eq(r, a / b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_mod_int(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_ints[n].mod_err) | 
					
						
							|  |  |  |             || (!err && !TEST_int_eq(r, a % b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-15 11:19:07 +08:00
										 |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_div_round_up_int(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_ints[n].div_round_up_err)) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |     s = safe_mod_int(a, b, &err); | 
					
						
							|  |  |  |     s = safe_add_int(safe_div_int(a, b, &err), s != 0, &err); | 
					
						
							|  |  |  |     if (!err && !TEST_int_eq(r, s)) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-28 07:21:40 +08:00
										 |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_neg_int(a, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_ints[n].neg_a_err) | 
					
						
							|  |  |  |             || (!err && !TEST_int_eq(r, -a))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_neg_int(b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_ints[n].neg_b_err) | 
					
						
							|  |  |  |             || (!err && !TEST_int_eq(r, -b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_abs_int(a, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_ints[n].abs_a_err) | 
					
						
							|  |  |  |             || (!err && !TEST_int_eq(r, a < 0 ? -a : a))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_abs_int(b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_ints[n].abs_b_err) | 
					
						
							|  |  |  |             || (!err && !TEST_int_eq(r, b < 0 ? -b : b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  |  err: | 
					
						
							|  |  |  |     TEST_info("a = %d  b = %d  r = %d  err = %d", a, b, r, err); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const struct { | 
					
						
							|  |  |  |     unsigned int a, b; | 
					
						
							| 
									
										
										
										
											2022-03-15 11:19:07 +08:00
										 |  |  |     int sum_err, sub_err, mul_err, div_err, mod_err, div_round_up_err; | 
					
						
							|  |  |  | } test_uints[] = {      /*  +  -  *  /  %  /r   */ | 
					
						
							|  |  |  |     { 3, 1,                 0, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { 1, 3,                 0, 1, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { UINT_MAX, 1,          1, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { UINT_MAX, 2,          1, 0, 1, 0, 0, 0 }, | 
					
						
							|  |  |  |     { UINT_MAX, 16,         1, 0, 1, 0, 0, 0 }, | 
					
						
							|  |  |  |     { UINT_MAX - 13, 16,    1, 0, 1, 0, 0, 0 }, | 
					
						
							|  |  |  |     { 1, UINT_MAX,          1, 1, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { 2, UINT_MAX,          1, 1, 1, 0, 0, 0 }, | 
					
						
							|  |  |  |     { UINT_MAX, 0,          0, 0, 0, 1, 1, 1 }, | 
					
						
							| 
									
										
										
										
											2021-10-28 07:21:40 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int test_uint_ops(int n) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int err; | 
					
						
							|  |  |  |     unsigned int r; | 
					
						
							|  |  |  |     const unsigned int a = test_uints[n].a, b = test_uints[n].b; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_add_uint(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_uints[n].sum_err) | 
					
						
							|  |  |  |             || (!err && !TEST_uint_eq(r, a + b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_sub_uint(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_uints[n].sub_err) | 
					
						
							|  |  |  |             || (!err && !TEST_uint_eq(r, a - b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_mul_uint(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_uints[n].mul_err) | 
					
						
							|  |  |  |             || (!err && !TEST_uint_eq(r, a * b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_div_uint(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_uints[n].div_err) | 
					
						
							|  |  |  |             || (!err && !TEST_uint_eq(r, a / b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_mod_uint(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_uints[n].mod_err) | 
					
						
							|  |  |  |             || (!err && !TEST_uint_eq(r, a % b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-15 11:19:07 +08:00
										 |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_div_round_up_uint(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_uints[n].div_round_up_err) | 
					
						
							|  |  |  |             || (!err && !TEST_uint_eq(r, a / b + (a % b != 0)))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-28 07:21:40 +08:00
										 |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_neg_uint(a, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, a != 0) || (!err && !TEST_uint_eq(r, 0))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_neg_uint(b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, b != 0) || (!err && !TEST_uint_eq(r, 0))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_abs_uint(a, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, 0) || !TEST_uint_eq(r, a)) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_abs_uint(b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, 0) || !TEST_uint_eq(r, b)) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |    return 1; | 
					
						
							|  |  |  |  err: | 
					
						
							|  |  |  |     TEST_info("a = %u  b = %u  r = %u  err = %d", a, b, r, err); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const struct { | 
					
						
							|  |  |  |     size_t a, b; | 
					
						
							| 
									
										
										
										
											2022-03-15 11:19:07 +08:00
										 |  |  |     int sum_err, sub_err, mul_err, div_err, mod_err, div_round_up_err; | 
					
						
							| 
									
										
										
										
											2021-10-28 07:21:40 +08:00
										 |  |  | } test_size_ts[] = { | 
					
						
							| 
									
										
										
										
											2022-03-15 11:19:07 +08:00
										 |  |  |     { 3, 1,                 0, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { 1, 3,                 0, 1, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { 36, 8,                0, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { SIZE_MAX, 1,          1, 0, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { SIZE_MAX, 2,          1, 0, 1, 0, 0, 0 }, | 
					
						
							|  |  |  |     { SIZE_MAX, 8,          1, 0, 1, 0, 0, 0 }, | 
					
						
							|  |  |  |     { SIZE_MAX - 3, 8,      1, 0, 1, 0, 0, 0 }, | 
					
						
							|  |  |  |     { 1, SIZE_MAX,          1, 1, 0, 0, 0, 0 }, | 
					
						
							|  |  |  |     { 2, SIZE_MAX,          1, 1, 1, 0, 0, 0 }, | 
					
						
							|  |  |  |     { 11, 0,                0, 0, 0, 1, 1, 1 }, | 
					
						
							| 
									
										
										
										
											2021-10-28 07:21:40 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int test_size_t_ops(int n) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int err; | 
					
						
							|  |  |  |     size_t r; | 
					
						
							|  |  |  |     const size_t a = test_size_ts[n].a, b = test_size_ts[n].b; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_add_size_t(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_size_ts[n].sum_err) | 
					
						
							|  |  |  |             || (!err && !TEST_size_t_eq(r, a + b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_sub_size_t(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_size_ts[n].sub_err) | 
					
						
							|  |  |  |             || (!err && !TEST_size_t_eq(r, a - b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_mul_size_t(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_size_ts[n].mul_err) | 
					
						
							|  |  |  |             || (!err && !TEST_size_t_eq(r, a * b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_div_size_t(a, b, &err); | 
					
						
							| 
									
										
										
										
											2022-03-15 11:19:07 +08:00
										 |  |  |     if (!TEST_int_eq(err, test_size_ts[n].div_err) | 
					
						
							| 
									
										
										
										
											2021-10-28 07:21:40 +08:00
										 |  |  |             || (!err && !TEST_size_t_eq(r, a / b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_mod_size_t(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_size_ts[n].mod_err) | 
					
						
							|  |  |  |             || (!err && !TEST_size_t_eq(r, a % b))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-15 11:19:07 +08:00
										 |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_div_round_up_size_t(a, b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_size_ts[n].div_round_up_err) | 
					
						
							|  |  |  |             || (!err && !TEST_size_t_eq(r, a / b + (a % b != 0)))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-28 07:21:40 +08:00
										 |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_neg_size_t(a, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, a != 0) || (!err && !TEST_size_t_eq(r, 0))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_neg_size_t(b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, b != 0) || (!err && !TEST_size_t_eq(r, 0))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_abs_size_t(a, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, 0) || !TEST_size_t_eq(r, a)) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = 0; | 
					
						
							|  |  |  |     r = safe_abs_size_t(b, &err); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, 0) || !TEST_size_t_eq(r, b)) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  |  err: | 
					
						
							|  |  |  |     TEST_info("a = %zu  b = %zu  r = %zu  err = %d", a, b, r, err); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const struct { | 
					
						
							|  |  |  |     int a, b, c; | 
					
						
							|  |  |  |     int err; | 
					
						
							|  |  |  | } test_muldiv_ints[] = { | 
					
						
							|  |  |  |     { 3, 1, 2,                          0 }, | 
					
						
							|  |  |  |     { 1, 3, 2,                          0 }, | 
					
						
							|  |  |  |     { -3, 1, 2,                         0 }, | 
					
						
							|  |  |  |     { 1, 3, -2,                         0 }, | 
					
						
							|  |  |  |     { INT_MAX, INT_MAX, INT_MAX,        0 }, | 
					
						
							|  |  |  |     { INT_MIN, INT_MIN, INT_MAX,        1 }, | 
					
						
							|  |  |  |     { INT_MIN, INT_MIN, INT_MIN,        0 }, | 
					
						
							|  |  |  |     { INT_MAX, 2, 4,                    0 }, | 
					
						
							|  |  |  |     { 8, INT_MAX, 4,                    1 }, | 
					
						
							|  |  |  |     { INT_MAX, 8, 4,                    1 }, | 
					
						
							|  |  |  |     { INT_MIN, 2, 4,                    1 }, | 
					
						
							|  |  |  |     { 8, INT_MIN, 4,                    1 }, | 
					
						
							|  |  |  |     { INT_MIN, 8, 4,                    1 }, | 
					
						
							|  |  |  |     { 3, 4, 0,                          1 }, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int test_int_muldiv(int n) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int err = 0; | 
					
						
							|  |  |  |     int r, real = 0; | 
					
						
							|  |  |  |     const int a = test_muldiv_ints[n].a; | 
					
						
							|  |  |  |     const int b = test_muldiv_ints[n].b; | 
					
						
							|  |  |  |     const int c = test_muldiv_ints[n].c; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     r = safe_muldiv_int(a, b, c, &err); | 
					
						
							|  |  |  |     if (c != 0) | 
					
						
							|  |  |  |         real = (int)((int64_t)a * (int64_t)b / (int64_t)c); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_muldiv_ints[n].err) | 
					
						
							|  |  |  |             || (!err && !TEST_int_eq(r, real))) { | 
					
						
							|  |  |  |         TEST_info("%d * %d / %d  r = %d  err = %d", a, b, c, r, err); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const struct { | 
					
						
							|  |  |  |     unsigned int a, b, c; | 
					
						
							|  |  |  |     int err; | 
					
						
							|  |  |  | } test_muldiv_uints[] = { | 
					
						
							|  |  |  |     { 3, 1, 2,                          0 }, | 
					
						
							|  |  |  |     { 1, 3, 2,                          0 }, | 
					
						
							|  |  |  |     { UINT_MAX, UINT_MAX, UINT_MAX,     0 }, | 
					
						
							|  |  |  |     { UINT_MAX, 2, 4,                   0 }, | 
					
						
							|  |  |  |     { 8, UINT_MAX, 4,                   1 }, | 
					
						
							|  |  |  |     { UINT_MAX, 8, 4,                   1 }, | 
					
						
							|  |  |  |     { 3, 4, 0,                          1 }, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int test_uint_muldiv(int n) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int err = 0; | 
					
						
							|  |  |  |     unsigned int r, real = 0; | 
					
						
							|  |  |  |     const unsigned int a = test_muldiv_uints[n].a; | 
					
						
							|  |  |  |     const unsigned int b = test_muldiv_uints[n].b; | 
					
						
							|  |  |  |     const unsigned int c = test_muldiv_uints[n].c; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     r = safe_muldiv_uint(a, b, c, &err); | 
					
						
							|  |  |  |     if (c != 0) | 
					
						
							|  |  |  |         real = (unsigned int)((uint64_t)a * (uint64_t)b / (uint64_t)c); | 
					
						
							|  |  |  |     if (!TEST_int_eq(err, test_muldiv_uints[n].err) | 
					
						
							|  |  |  |             || (!err && !TEST_uint_eq(r, real))) { | 
					
						
							|  |  |  |         TEST_info("%u * %u / %u  r = %u  err = %d", a, b, c, r, err); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int setup_tests(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ADD_ALL_TESTS(test_int_ops, OSSL_NELEM(test_ints)); | 
					
						
							|  |  |  |     ADD_ALL_TESTS(test_uint_ops, OSSL_NELEM(test_uints)); | 
					
						
							|  |  |  |     ADD_ALL_TESTS(test_size_t_ops, OSSL_NELEM(test_size_ts)); | 
					
						
							|  |  |  |     ADD_ALL_TESTS(test_int_muldiv, OSSL_NELEM(test_muldiv_ints)); | 
					
						
							|  |  |  |     ADD_ALL_TESTS(test_uint_muldiv, OSSL_NELEM(test_muldiv_uints)); | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } |