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