constant_time_test.c 12 KB

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