1 /* 2 * Copyright 2021-2024 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, 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 }, 53 }; 54 55 static int test_int_ops(int n) 56 { 57 int err, r, s; 58 const int a = test_ints[n].a, b = test_ints[n].b; 59 60 err = 0; 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))) 64 goto err; 65 66 err = 0; 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))) 70 goto err; 71 72 err = 0; 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))) 76 goto err; 77 78 err = 0; 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))) 82 goto err; 83 84 err = 0; 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))) 88 goto err; 89 90 err = 0; 91 r = safe_div_round_up_int(a, b, &err); 92 if (!TEST_int_eq(err, test_ints[n].div_round_up_err)) 93 goto 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)) 97 goto err; 98 99 err = 0; 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))) 103 goto err; 104 105 err = 0; 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))) 109 goto err; 110 111 err = 0; 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))) 115 goto err; 116 117 err = 0; 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))) 121 goto err; 122 return 1; 123 err: 124 TEST_info("a = %d b = %d r = %d err = %d", a, b, r, err); 125 return 0; 126 } 127 128 static const struct { 129 unsigned int a, b; 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 }, 141 }; 142 143 static int test_uint_ops(int n) 144 { 145 int err; 146 unsigned int r; 147 const unsigned int a = test_uints[n].a, b = test_uints[n].b; 148 149 err = 0; 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))) 153 goto err; 154 155 err = 0; 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))) 159 goto err; 160 161 err = 0; 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))) 165 goto err; 166 167 err = 0; 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))) 171 goto err; 172 173 err = 0; 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))) 177 goto err; 178 179 err = 0; 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)))) 183 goto err; 184 185 err = 0; 186 r = safe_neg_uint(a, &err); 187 if (!TEST_int_eq(err, a != 0) || (!err && !TEST_uint_eq(r, 0))) 188 goto err; 189 190 err = 0; 191 r = safe_neg_uint(b, &err); 192 if (!TEST_int_eq(err, b != 0) || (!err && !TEST_uint_eq(r, 0))) 193 goto err; 194 195 err = 0; 196 r = safe_abs_uint(a, &err); 197 if (!TEST_int_eq(err, 0) || !TEST_uint_eq(r, a)) 198 goto err; 199 200 err = 0; 201 r = safe_abs_uint(b, &err); 202 if (!TEST_int_eq(err, 0) || !TEST_uint_eq(r, b)) 203 goto err; 204 return 1; 205 err: 206 TEST_info("a = %u b = %u r = %u err = %d", a, b, r, err); 207 return 0; 208 } 209 210 static const struct { 211 size_t a, b; 212 int sum_err, sub_err, mul_err, div_err, mod_err, div_round_up_err; 213 } test_size_ts[] = { 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 }, 224 }; 225 226 static int test_size_t_ops(int n) 227 { 228 int err; 229 size_t r; 230 const size_t a = test_size_ts[n].a, b = test_size_ts[n].b; 231 232 err = 0; 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))) 236 goto err; 237 238 err = 0; 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))) 242 goto err; 243 244 err = 0; 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))) 248 goto err; 249 250 err = 0; 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))) 254 goto err; 255 256 err = 0; 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))) 260 goto err; 261 262 err = 0; 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)))) 266 goto err; 267 268 err = 0; 269 r = safe_neg_size_t(a, &err); 270 if (!TEST_int_eq(err, a != 0) || (!err && !TEST_size_t_eq(r, 0))) 271 goto err; 272 273 err = 0; 274 r = safe_neg_size_t(b, &err); 275 if (!TEST_int_eq(err, b != 0) || (!err && !TEST_size_t_eq(r, 0))) 276 goto err; 277 278 err = 0; 279 r = safe_abs_size_t(a, &err); 280 if (!TEST_int_eq(err, 0) || !TEST_size_t_eq(r, a)) 281 goto err; 282 283 err = 0; 284 r = safe_abs_size_t(b, &err); 285 if (!TEST_int_eq(err, 0) || !TEST_size_t_eq(r, b)) 286 goto err; 287 return 1; 288 err: 289 TEST_info("a = %zu b = %zu r = %zu err = %d", a, b, r, err); 290 return 0; 291 } 292 293 static const struct { 294 int a, b, c; 295 int err; 296 } test_muldiv_ints[] = { 297 { 3, 1, 2, 0 }, 298 { 1, 3, 2, 0 }, 299 { -3, 1, 2, 0 }, 300 { 1, 3, -2, 0 }, 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 }, 310 { 3, 4, 0, 1 }, 311 }; 312 313 static int test_int_muldiv(int n) 314 { 315 int err = 0; 316 int r, real = 0; 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; 320 321 r = safe_muldiv_int(a, b, c, &err); 322 if (c != 0) 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); 327 return 0; 328 } 329 return 1; 330 } 331 332 static const struct { 333 unsigned int a, b, c; 334 int err; 335 } test_muldiv_uints[] = { 336 { 3, 1, 2, 0 }, 337 { 1, 3, 2, 0 }, 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 }, 342 { 3, 4, 0, 1 }, 343 }; 344 345 static int test_uint_muldiv(int n) 346 { 347 int err = 0; 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; 352 353 r = safe_muldiv_uint(a, b, c, &err); 354 if (c != 0) 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); 359 return 0; 360 } 361 return 1; 362 } 363 364 int setup_tests(void) 365 { 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)); 371 return 1; 372 } 373