1 /* 2 * Copyright 2014-2018 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 #include "internal/nelem.h" 14 #include "internal/constant_time.h" 15 #include "testutil.h" 16 #include "internal/numbers.h" 17 18 static const unsigned int CONSTTIME_TRUE = (unsigned)(~0); 19 static const unsigned int CONSTTIME_FALSE = 0; 20 static const unsigned char CONSTTIME_TRUE_8 = 0xff; 21 static const unsigned char CONSTTIME_FALSE_8 = 0; 22 static const size_t CONSTTIME_TRUE_S = ~((size_t)0); 23 static const size_t CONSTTIME_FALSE_S = 0; 24 static uint32_t CONSTTIME_TRUE_32 = (uint32_t)(~(uint32_t)0); 25 static uint32_t CONSTTIME_FALSE_32 = 0; 26 static uint64_t CONSTTIME_TRUE_64 = (uint64_t)(~(uint64_t)0); 27 static uint64_t CONSTTIME_FALSE_64 = 0; 28 29 static unsigned int test_values[] = { 30 0, 1, 1024, 12345, 32000, UINT_MAX / 2 - 1, 31 UINT_MAX / 2, UINT_MAX / 2 + 1, UINT_MAX - 1, 32 UINT_MAX 33 }; 34 35 static unsigned char test_values_8[] = { 36 0, 1, 2, 20, 32, 127, 128, 129, 255 37 }; 38 39 static int signed_test_values[] = { 40 0, 1, -1, 1024, -1024, 12345, -12345, 41 32000, -32000, INT_MAX, INT_MIN, INT_MAX - 1, 42 INT_MIN + 1 43 }; 44 45 static size_t test_values_s[] = { 46 0, 1, 1024, 12345, 32000, SIZE_MAX / 2 - 1, 47 SIZE_MAX / 2, SIZE_MAX / 2 + 1, SIZE_MAX - 1, 48 SIZE_MAX 49 }; 50 51 static uint32_t test_values_32[] = { 52 0, 1, 1024, 12345, 32000, UINT32_MAX / 2, UINT32_MAX / 2 + 1, 53 UINT32_MAX - 1, UINT32_MAX 54 }; 55 56 static uint64_t test_values_64[] = { 57 0, 1, 1024, 12345, 32000, 32000000, 32000000001, UINT64_MAX / 2, 58 UINT64_MAX / 2 + 1, UINT64_MAX - 1, UINT64_MAX 59 }; 60 61 static int test_binary_op(unsigned int (*op)(unsigned int a, unsigned int b), 62 const char *op_name, unsigned int a, unsigned int b, 63 int is_true) 64 { 65 if (is_true && !TEST_uint_eq(op(a, b), CONSTTIME_TRUE)) 66 return 0; 67 if (!is_true && !TEST_uint_eq(op(a, b), CONSTTIME_FALSE)) 68 return 0; 69 return 1; 70 } 71 72 static int test_binary_op_8(unsigned char (*op)(unsigned int a, unsigned int b), 73 const char *op_name, unsigned int a, 74 unsigned int b, int is_true) 75 { 76 if (is_true && !TEST_uint_eq(op(a, b), CONSTTIME_TRUE_8)) 77 return 0; 78 if (!is_true && !TEST_uint_eq(op(a, b), CONSTTIME_FALSE_8)) 79 return 0; 80 return 1; 81 } 82 83 static int test_binary_op_s(size_t (*op)(size_t a, size_t b), 84 const char *op_name, size_t a, size_t b, 85 int is_true) 86 { 87 if (is_true && !TEST_size_t_eq(op(a, b), CONSTTIME_TRUE_S)) 88 return 0; 89 if (!is_true && !TEST_uint_eq(op(a, b), CONSTTIME_FALSE_S)) 90 return 0; 91 return 1; 92 } 93 94 static int test_binary_op_64(uint64_t (*op)(uint64_t a, uint64_t b), 95 const char *op_name, uint64_t a, uint64_t b, 96 int is_true) 97 { 98 uint64_t c = op(a, b); 99 100 if (is_true && c != CONSTTIME_TRUE_64) { 101 TEST_error("TRUE %s op failed", op_name); 102 BIO_printf(bio_err, "a=%jx b=%jx\n", a, b); 103 return 0; 104 } else if (!is_true && c != CONSTTIME_FALSE_64) { 105 TEST_error("FALSE %s op failed", op_name); 106 BIO_printf(bio_err, "a=%jx b=%jx\n", a, b); 107 return 0; 108 } 109 return 1; 110 } 111 112 static int test_is_zero(int i) 113 { 114 unsigned int a = test_values[i]; 115 116 if (a == 0 && !TEST_uint_eq(constant_time_is_zero(a), CONSTTIME_TRUE)) 117 return 0; 118 if (a != 0 && !TEST_uint_eq(constant_time_is_zero(a), CONSTTIME_FALSE)) 119 return 0; 120 return 1; 121 } 122 123 static int test_is_zero_8(int i) 124 { 125 unsigned int a = test_values_8[i]; 126 127 if (a == 0 && !TEST_uint_eq(constant_time_is_zero_8(a), CONSTTIME_TRUE_8)) 128 return 0; 129 if (a != 0 && !TEST_uint_eq(constant_time_is_zero_8(a), CONSTTIME_FALSE_8)) 130 return 0; 131 return 1; 132 } 133 134 static int test_is_zero_32(int i) 135 { 136 uint32_t a = test_values_32[i]; 137 138 if (a == 0 && !TEST_true(constant_time_is_zero_32(a) == CONSTTIME_TRUE_32)) 139 return 0; 140 if (a != 0 && !TEST_true(constant_time_is_zero_32(a) == CONSTTIME_FALSE_32)) 141 return 0; 142 return 1; 143 } 144 145 static int test_is_zero_s(int i) 146 { 147 size_t a = test_values_s[i]; 148 149 if (a == 0 && !TEST_size_t_eq(constant_time_is_zero_s(a), CONSTTIME_TRUE_S)) 150 return 0; 151 if (a != 0 && !TEST_uint_eq(constant_time_is_zero_s(a), CONSTTIME_FALSE_S)) 152 return 0; 153 return 1; 154 } 155 156 static int test_select(unsigned int a, unsigned int b) 157 { 158 if (!TEST_uint_eq(constant_time_select(CONSTTIME_TRUE, a, b), a)) 159 return 0; 160 if (!TEST_uint_eq(constant_time_select(CONSTTIME_FALSE, a, b), b)) 161 return 0; 162 return 1; 163 } 164 165 static int test_select_8(unsigned char a, unsigned char b) 166 { 167 if (!TEST_uint_eq(constant_time_select_8(CONSTTIME_TRUE_8, a, b), a)) 168 return 0; 169 if (!TEST_uint_eq(constant_time_select_8(CONSTTIME_FALSE_8, a, b), b)) 170 return 0; 171 return 1; 172 } 173 174 static int test_select_32(uint32_t a, uint32_t b) 175 { 176 if (!TEST_true(constant_time_select_32(CONSTTIME_TRUE_32, a, b) == a)) 177 return 0; 178 if (!TEST_true(constant_time_select_32(CONSTTIME_FALSE_32, a, b) == b)) 179 return 0; 180 return 1; 181 } 182 183 static int test_select_s(size_t a, size_t b) 184 { 185 if (!TEST_uint_eq(constant_time_select_s(CONSTTIME_TRUE_S, a, b), a)) 186 return 0; 187 if (!TEST_uint_eq(constant_time_select_s(CONSTTIME_FALSE_S, a, b), b)) 188 return 0; 189 return 1; 190 } 191 192 static int test_select_64(uint64_t a, uint64_t b) 193 { 194 uint64_t selected = constant_time_select_64(CONSTTIME_TRUE_64, a, b); 195 196 if (selected != a) { 197 TEST_error("test_select_64 TRUE failed"); 198 BIO_printf(bio_err, "a=%jx b=%jx got %jx wanted a\n", a, b, selected); 199 return 0; 200 } 201 selected = constant_time_select_64(CONSTTIME_FALSE_64, a, b); 202 if (selected != b) { 203 BIO_printf(bio_err, "a=%jx b=%jx got %jx wanted b\n", a, b, selected); 204 return 0; 205 } 206 return 1; 207 } 208 209 static int test_select_int(int a, int b) 210 { 211 if (!TEST_int_eq(constant_time_select_int(CONSTTIME_TRUE, a, b), a)) 212 return 0; 213 if (!TEST_int_eq(constant_time_select_int(CONSTTIME_FALSE, a, b), b)) 214 return 0; 215 return 1; 216 } 217 218 static int test_eq_int_8(int a, int b) 219 { 220 if (a == b && !TEST_int_eq(constant_time_eq_int_8(a, b), CONSTTIME_TRUE_8)) 221 return 0; 222 if (a != b && !TEST_int_eq(constant_time_eq_int_8(a, b), CONSTTIME_FALSE_8)) 223 return 0; 224 return 1; 225 } 226 227 static int test_eq_s(size_t a, size_t b) 228 { 229 if (a == b && !TEST_size_t_eq(constant_time_eq_s(a, b), CONSTTIME_TRUE_S)) 230 return 0; 231 if (a != b && !TEST_int_eq(constant_time_eq_s(a, b), CONSTTIME_FALSE_S)) 232 return 0; 233 return 1; 234 } 235 236 static int test_eq_int(int a, int b) 237 { 238 if (a == b && !TEST_uint_eq(constant_time_eq_int(a, b), CONSTTIME_TRUE)) 239 return 0; 240 if (a != b && !TEST_uint_eq(constant_time_eq_int(a, b), CONSTTIME_FALSE)) 241 return 0; 242 return 1; 243 } 244 245 static int test_sizeofs(void) 246 { 247 if (!TEST_uint_eq(OSSL_NELEM(test_values), OSSL_NELEM(test_values_s))) 248 return 0; 249 return 1; 250 } 251 252 static int test_binops(int i) 253 { 254 unsigned int a = test_values[i]; 255 int j; 256 int ret = 1; 257 258 for (j = 0; j < (int)OSSL_NELEM(test_values); ++j) { 259 unsigned int b = test_values[j]; 260 261 if (!test_select(a, b) 262 || !test_binary_op(&constant_time_lt, "ct_lt", 263 a, b, a < b) 264 || !test_binary_op(&constant_time_lt, "constant_time_lt", 265 b, a, b < a) 266 || !test_binary_op(&constant_time_ge, "constant_time_ge", 267 a, b, a >= b) 268 || !test_binary_op(&constant_time_ge, "constant_time_ge", 269 b, a, b >= a) 270 || !test_binary_op(&constant_time_eq, "constant_time_eq", 271 a, b, a == b) 272 || !test_binary_op(&constant_time_eq, "constant_time_eq", 273 b, a, b == a)) 274 ret = 0; 275 } 276 return ret; 277 } 278 279 static int test_binops_8(int i) 280 { 281 unsigned int a = test_values_8[i]; 282 int j; 283 int ret = 1; 284 285 for (j = 0; j < (int)OSSL_NELEM(test_values_8); ++j) { 286 unsigned int b = test_values_8[j]; 287 288 if (!test_binary_op_8(&constant_time_lt_8, "constant_time_lt_8", 289 a, b, a < b) 290 || !test_binary_op_8(&constant_time_lt_8, "constant_time_lt_8", 291 b, a, b < a) 292 || !test_binary_op_8(&constant_time_ge_8, "constant_time_ge_8", 293 a, b, a >= b) 294 || !test_binary_op_8(&constant_time_ge_8, "constant_time_ge_8", 295 b, a, b >= a) 296 || !test_binary_op_8(&constant_time_eq_8, "constant_time_eq_8", 297 a, b, a == b) 298 || !test_binary_op_8(&constant_time_eq_8, "constant_time_eq_8", 299 b, a, b == a)) 300 ret = 0; 301 } 302 return ret; 303 } 304 305 static int test_binops_s(int i) 306 { 307 size_t a = test_values_s[i]; 308 int j; 309 int ret = 1; 310 311 for (j = 0; j < (int)OSSL_NELEM(test_values_s); ++j) { 312 size_t b = test_values_s[j]; 313 314 if (!test_select_s(a, b) 315 || !test_eq_s(a, b) 316 || !test_binary_op_s(&constant_time_lt_s, "constant_time_lt_s", 317 a, b, a < b) 318 || !test_binary_op_s(&constant_time_lt_s, "constant_time_lt_s", 319 b, a, b < a) 320 || !test_binary_op_s(&constant_time_ge_s, "constant_time_ge_s", 321 a, b, a >= b) 322 || !test_binary_op_s(&constant_time_ge_s, "constant_time_ge_s", 323 b, a, b >= a) 324 || !test_binary_op_s(&constant_time_eq_s, "constant_time_eq_s", 325 a, b, a == b) 326 || !test_binary_op_s(&constant_time_eq_s, "constant_time_eq_s", 327 b, a, b == a)) 328 ret = 0; 329 } 330 return ret; 331 } 332 333 static int test_signed(int i) 334 { 335 int c = signed_test_values[i]; 336 unsigned int j; 337 int ret = 1; 338 339 for (j = 0; j < OSSL_NELEM(signed_test_values); ++j) { 340 int d = signed_test_values[j]; 341 342 if (!test_select_int(c, d) 343 || !test_eq_int(c, d) 344 || !test_eq_int_8(c, d)) 345 ret = 0; 346 } 347 return ret; 348 } 349 350 static int test_8values(int i) 351 { 352 unsigned char e = test_values_8[i]; 353 unsigned int j; 354 int ret = 1; 355 356 for (j = 0; j < sizeof(test_values_8); ++j) { 357 unsigned char f = test_values_8[j]; 358 359 if (!test_select_8(e, f)) 360 ret = 0; 361 } 362 return ret; 363 } 364 365 static int test_32values(int i) 366 { 367 uint32_t e = test_values_32[i]; 368 size_t j; 369 int ret = 1; 370 371 for (j = 0; j < OSSL_NELEM(test_values_32); j++) { 372 uint32_t f = test_values_32[j]; 373 374 if (!test_select_32(e, f)) 375 ret = 0; 376 } 377 return ret; 378 } 379 380 static int test_64values(int i) 381 { 382 uint64_t g = test_values_64[i]; 383 int j, ret = 1; 384 385 for (j = i + 1; j < (int)OSSL_NELEM(test_values_64); j++) { 386 uint64_t h = test_values_64[j]; 387 388 if (!test_binary_op_64(&constant_time_lt_64, "constant_time_lt_64", 389 g, h, g < h) 390 || !test_select_64(g, h)) { 391 TEST_info("test_64values failed i=%d j=%d", i, j); 392 ret = 0; 393 } 394 } 395 return ret; 396 } 397 398 int setup_tests(void) 399 { 400 ADD_TEST(test_sizeofs); 401 ADD_ALL_TESTS(test_is_zero, OSSL_NELEM(test_values)); 402 ADD_ALL_TESTS(test_is_zero_8, OSSL_NELEM(test_values_8)); 403 ADD_ALL_TESTS(test_is_zero_32, OSSL_NELEM(test_values_32)); 404 ADD_ALL_TESTS(test_is_zero_s, OSSL_NELEM(test_values_s)); 405 ADD_ALL_TESTS(test_binops, OSSL_NELEM(test_values)); 406 ADD_ALL_TESTS(test_binops_8, OSSL_NELEM(test_values_8)); 407 ADD_ALL_TESTS(test_binops_s, OSSL_NELEM(test_values_s)); 408 ADD_ALL_TESTS(test_signed, OSSL_NELEM(signed_test_values)); 409 ADD_ALL_TESTS(test_8values, OSSL_NELEM(test_values_8)); 410 ADD_ALL_TESTS(test_32values, OSSL_NELEM(test_values_32)); 411 ADD_ALL_TESTS(test_64values, OSSL_NELEM(test_values_64)); 412 return 1; 413 } 414