test_crypto_slow.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. /* Copyright (c) 2001-2004, Roger Dingledine.
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2018, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #include "orconfig.h"
  6. #define CRYPTO_S2K_PRIVATE
  7. #include "core/or/or.h"
  8. #include "test/test.h"
  9. #include "lib/crypt_ops/crypto_curve25519.h"
  10. #include "lib/crypt_ops/crypto_ed25519.h"
  11. #include "lib/crypt_ops/crypto_s2k.h"
  12. #include "lib/crypt_ops/crypto_pwbox.h"
  13. #include "lib/crypt_ops/crypto_rand.h"
  14. #if defined(HAVE_LIBSCRYPT_H) && defined(HAVE_LIBSCRYPT_SCRYPT)
  15. #define HAVE_LIBSCRYPT
  16. #include <libscrypt.h>
  17. #endif
  18. #include <openssl/evp.h>
  19. /** Run unit tests for our secret-to-key passphrase hashing functionality. */
  20. static void
  21. test_crypto_s2k_rfc2440(void *arg)
  22. {
  23. char buf[29];
  24. char buf2[29];
  25. char *buf3 = NULL;
  26. int i;
  27. (void)arg;
  28. memset(buf, 0, sizeof(buf));
  29. memset(buf2, 0, sizeof(buf2));
  30. buf3 = tor_malloc(65536);
  31. memset(buf3, 0, 65536);
  32. secret_to_key_rfc2440(buf+9, 20, "", 0, buf);
  33. crypto_digest(buf2+9, buf3, 1024);
  34. tt_mem_op(buf,OP_EQ, buf2, 29);
  35. memcpy(buf,"vrbacrda",8);
  36. memcpy(buf2,"vrbacrda",8);
  37. buf[8] = 96;
  38. buf2[8] = 96;
  39. secret_to_key_rfc2440(buf+9, 20, "12345678", 8, buf);
  40. for (i = 0; i < 65536; i += 16) {
  41. memcpy(buf3+i, "vrbacrda12345678", 16);
  42. }
  43. crypto_digest(buf2+9, buf3, 65536);
  44. tt_mem_op(buf,OP_EQ, buf2, 29);
  45. done:
  46. tor_free(buf3);
  47. }
  48. static void
  49. run_s2k_tests(const unsigned flags, const unsigned type,
  50. int speclen, const int keylen, int legacy)
  51. {
  52. uint8_t buf[S2K_MAXLEN], buf2[S2K_MAXLEN], buf3[S2K_MAXLEN];
  53. int r;
  54. size_t sz;
  55. const char pw1[] = "You can't come in here unless you say swordfish!";
  56. const char pw2[] = "Now, I give you one more guess.";
  57. r = secret_to_key_new(buf, sizeof(buf), &sz,
  58. pw1, strlen(pw1), flags);
  59. tt_int_op(r, OP_EQ, S2K_OKAY);
  60. tt_int_op(buf[0], OP_EQ, type);
  61. tt_int_op(sz, OP_EQ, keylen + speclen);
  62. if (legacy) {
  63. memmove(buf, buf+1, sz-1);
  64. --sz;
  65. --speclen;
  66. }
  67. tt_int_op(S2K_OKAY, OP_EQ,
  68. secret_to_key_check(buf, sz, pw1, strlen(pw1)));
  69. tt_int_op(S2K_BAD_SECRET, OP_EQ,
  70. secret_to_key_check(buf, sz, pw2, strlen(pw2)));
  71. /* Move key to buf2, and clear it. */
  72. memset(buf3, 0, sizeof(buf3));
  73. memcpy(buf2, buf+speclen, keylen);
  74. memset(buf+speclen, 0, sz - speclen);
  75. /* Derivekey should produce the same results. */
  76. tt_int_op(S2K_OKAY, OP_EQ,
  77. secret_to_key_derivekey(buf3, keylen, buf, speclen, pw1, strlen(pw1)));
  78. tt_mem_op(buf2, OP_EQ, buf3, keylen);
  79. /* Derivekey with a longer output should fill the output. */
  80. memset(buf2, 0, sizeof(buf2));
  81. tt_int_op(S2K_OKAY, OP_EQ,
  82. secret_to_key_derivekey(buf2, sizeof(buf2), buf, speclen,
  83. pw1, strlen(pw1)));
  84. tt_mem_op(buf2, OP_NE, buf3, sizeof(buf2));
  85. memset(buf3, 0, sizeof(buf3));
  86. tt_int_op(S2K_OKAY, OP_EQ,
  87. secret_to_key_derivekey(buf3, sizeof(buf3), buf, speclen,
  88. pw1, strlen(pw1)));
  89. tt_mem_op(buf2, OP_EQ, buf3, sizeof(buf3));
  90. tt_assert(!tor_mem_is_zero((char*)buf2+keylen, sizeof(buf2)-keylen));
  91. done:
  92. ;
  93. }
  94. static void
  95. test_crypto_s2k_general(void *arg)
  96. {
  97. const char *which = arg;
  98. if (!strcmp(which, "scrypt")) {
  99. run_s2k_tests(0, 2, 19, 32, 0);
  100. } else if (!strcmp(which, "scrypt-low")) {
  101. run_s2k_tests(S2K_FLAG_LOW_MEM, 2, 19, 32, 0);
  102. } else if (!strcmp(which, "pbkdf2")) {
  103. run_s2k_tests(S2K_FLAG_USE_PBKDF2, 1, 18, 20, 0);
  104. } else if (!strcmp(which, "rfc2440")) {
  105. run_s2k_tests(S2K_FLAG_NO_SCRYPT, 0, 10, 20, 0);
  106. } else if (!strcmp(which, "rfc2440-legacy")) {
  107. run_s2k_tests(S2K_FLAG_NO_SCRYPT, 0, 10, 20, 1);
  108. } else {
  109. tt_fail();
  110. }
  111. }
  112. #if defined(HAVE_LIBSCRYPT) && defined(HAVE_EVP_PBE_SCRYPT)
  113. static void
  114. test_libscrypt_eq_openssl(void *arg)
  115. {
  116. uint8_t buf1[64];
  117. uint8_t buf2[64];
  118. uint64_t N;
  119. uint32_t r, p;
  120. uint64_t maxmem = 0; // --> SCRYPT_MAX_MEM in OpenSSL.
  121. int libscrypt_retval, openssl_retval;
  122. size_t dk_len = 64;
  123. (void)arg;
  124. memset(buf1,0,64);
  125. memset(buf2,0,64);
  126. /* NOTE: we're using N,r the way OpenSSL and libscrypt define them,
  127. * not the way draft-josefsson-scrypt-kdf-00.txt define them.
  128. */
  129. N = 16;
  130. r = 1;
  131. p = 1;
  132. libscrypt_retval =
  133. libscrypt_scrypt((const uint8_t *)"", 0, (const uint8_t *)"", 0,
  134. N, r, p, buf1, dk_len);
  135. openssl_retval =
  136. EVP_PBE_scrypt((const char *)"", 0, (const unsigned char *)"", 0,
  137. N, r, p, maxmem, buf2, dk_len);
  138. tt_int_op(libscrypt_retval, OP_EQ, 0);
  139. tt_int_op(openssl_retval, OP_EQ, 1);
  140. tt_mem_op(buf1, OP_EQ, buf2, 64);
  141. memset(buf1,0,64);
  142. memset(buf2,0,64);
  143. N = 1024;
  144. r = 8;
  145. p = 16;
  146. libscrypt_retval =
  147. libscrypt_scrypt((const uint8_t *)"password", strlen("password"),
  148. (const uint8_t *)"NaCl", strlen("NaCl"),
  149. N, r, p, buf1, dk_len);
  150. openssl_retval =
  151. EVP_PBE_scrypt((const char *)"password", strlen("password"),
  152. (const unsigned char *)"NaCl", strlen("NaCl"),
  153. N, r, p, maxmem, buf2, dk_len);
  154. tt_int_op(libscrypt_retval, OP_EQ, 0);
  155. tt_int_op(openssl_retval, OP_EQ, 1);
  156. tt_mem_op(buf1, OP_EQ, buf2, 64);
  157. memset(buf1,0,64);
  158. memset(buf2,0,64);
  159. N = 16384;
  160. r = 8;
  161. p = 1;
  162. libscrypt_retval =
  163. libscrypt_scrypt((const uint8_t *)"pleaseletmein",
  164. strlen("pleaseletmein"),
  165. (const uint8_t *)"SodiumChloride",
  166. strlen("SodiumChloride"),
  167. N, r, p, buf1, dk_len);
  168. openssl_retval =
  169. EVP_PBE_scrypt((const char *)"pleaseletmein",
  170. strlen("pleaseletmein"),
  171. (const unsigned char *)"SodiumChloride",
  172. strlen("SodiumChloride"),
  173. N, r, p, maxmem, buf2, dk_len);
  174. tt_int_op(libscrypt_retval, OP_EQ, 0);
  175. tt_int_op(openssl_retval, OP_EQ, 1);
  176. tt_mem_op(buf1, OP_EQ, buf2, 64);
  177. memset(buf1,0,64);
  178. memset(buf2,0,64);
  179. N = 1048576;
  180. maxmem = 2 * 1024 * 1024 * (uint64_t)1024; // 2 GB
  181. libscrypt_retval =
  182. libscrypt_scrypt((const uint8_t *)"pleaseletmein",
  183. strlen("pleaseletmein"),
  184. (const uint8_t *)"SodiumChloride",
  185. strlen("SodiumChloride"),
  186. N, r, p, buf1, dk_len);
  187. openssl_retval =
  188. EVP_PBE_scrypt((const char *)"pleaseletmein",
  189. strlen("pleaseletmein"),
  190. (const unsigned char *)"SodiumChloride",
  191. strlen("SodiumChloride"),
  192. N, r, p, maxmem, buf2, dk_len);
  193. tt_int_op(libscrypt_retval, OP_EQ, 0);
  194. tt_int_op(openssl_retval, OP_EQ, 1);
  195. tt_mem_op(buf1, OP_EQ, buf2, 64);
  196. done:
  197. return;
  198. }
  199. #endif /* defined(HAVE_LIBSCRYPT) && defined(HAVE_EVP_PBE_SCRYPT) */
  200. static void
  201. test_crypto_s2k_errors(void *arg)
  202. {
  203. uint8_t buf[S2K_MAXLEN], buf2[S2K_MAXLEN];
  204. size_t sz;
  205. (void)arg;
  206. /* Bogus specifiers: simple */
  207. tt_int_op(S2K_BAD_LEN, OP_EQ,
  208. secret_to_key_derivekey(buf, sizeof(buf),
  209. (const uint8_t*)"", 0, "ABC", 3));
  210. tt_int_op(S2K_BAD_ALGORITHM, OP_EQ,
  211. secret_to_key_derivekey(buf, sizeof(buf),
  212. (const uint8_t*)"\x10", 1, "ABC", 3));
  213. tt_int_op(S2K_BAD_LEN, OP_EQ,
  214. secret_to_key_derivekey(buf, sizeof(buf),
  215. (const uint8_t*)"\x01\x02", 2, "ABC", 3));
  216. tt_int_op(S2K_BAD_LEN, OP_EQ,
  217. secret_to_key_check((const uint8_t*)"", 0, "ABC", 3));
  218. tt_int_op(S2K_BAD_ALGORITHM, OP_EQ,
  219. secret_to_key_check((const uint8_t*)"\x10", 1, "ABC", 3));
  220. tt_int_op(S2K_BAD_LEN, OP_EQ,
  221. secret_to_key_check((const uint8_t*)"\x01\x02", 2, "ABC", 3));
  222. /* too long gets "BAD_LEN" too */
  223. memset(buf, 0, sizeof(buf));
  224. buf[0] = 2;
  225. tt_int_op(S2K_BAD_LEN, OP_EQ,
  226. secret_to_key_derivekey(buf2, sizeof(buf2),
  227. buf, sizeof(buf), "ABC", 3));
  228. /* Truncated output */
  229. #ifdef HAVE_LIBSCRYPT
  230. tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_new(buf, 50, &sz,
  231. "ABC", 3, 0));
  232. tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_new(buf, 50, &sz,
  233. "ABC", 3, S2K_FLAG_LOW_MEM));
  234. #endif /* defined(HAVE_LIBSCRYPT) */
  235. tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_new(buf, 37, &sz,
  236. "ABC", 3, S2K_FLAG_USE_PBKDF2));
  237. tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_new(buf, 29, &sz,
  238. "ABC", 3, S2K_FLAG_NO_SCRYPT));
  239. #ifdef HAVE_LIBSCRYPT
  240. tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_make_specifier(buf, 18, 0));
  241. tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_make_specifier(buf, 18,
  242. S2K_FLAG_LOW_MEM));
  243. #endif
  244. tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_make_specifier(buf, 17,
  245. S2K_FLAG_USE_PBKDF2));
  246. tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_make_specifier(buf, 9,
  247. S2K_FLAG_NO_SCRYPT));
  248. /* Now try using type-specific bogus specifiers. */
  249. /* It's a bad pbkdf2 buffer if it has an iteration count that would overflow
  250. * int32_t. */
  251. memset(buf, 0, sizeof(buf));
  252. buf[0] = 1; /* pbkdf2 */
  253. buf[17] = 100; /* 1<<100 is much bigger than INT32_MAX */
  254. tt_int_op(S2K_BAD_PARAMS, OP_EQ,
  255. secret_to_key_derivekey(buf2, sizeof(buf2),
  256. buf, 18, "ABC", 3));
  257. #ifdef HAVE_LIBSCRYPT
  258. /* It's a bad scrypt buffer if N would overflow uint64 */
  259. memset(buf, 0, sizeof(buf));
  260. buf[0] = 2; /* scrypt */
  261. buf[17] = 100; /* 1<<100 is much bigger than UINT64_MAX */
  262. tt_int_op(S2K_BAD_PARAMS, OP_EQ,
  263. secret_to_key_derivekey(buf2, sizeof(buf2),
  264. buf, 19, "ABC", 3));
  265. #endif /* defined(HAVE_LIBSCRYPT) */
  266. done:
  267. ;
  268. }
  269. static void
  270. test_crypto_scrypt_vectors(void *arg)
  271. {
  272. char *mem_op_hex_tmp = NULL;
  273. uint8_t spec[64], out[64];
  274. (void)arg;
  275. #ifndef HAVE_LIBSCRYPT
  276. if (1)
  277. tt_skip();
  278. #endif
  279. /* Test vectors from
  280. http://tools.ietf.org/html/draft-josefsson-scrypt-kdf-00 section 11.
  281. Note that the names of 'r' and 'N' are switched in that section. Or
  282. possibly in libscrypt.
  283. */
  284. base16_decode((char*)spec, sizeof(spec),
  285. "0400", 4);
  286. memset(out, 0x00, sizeof(out));
  287. tt_int_op(64, OP_EQ,
  288. secret_to_key_compute_key(out, 64, spec, 2, "", 0, 2));
  289. test_memeq_hex(out,
  290. "77d6576238657b203b19ca42c18a0497"
  291. "f16b4844e3074ae8dfdffa3fede21442"
  292. "fcd0069ded0948f8326a753a0fc81f17"
  293. "e8d3e0fb2e0d3628cf35e20c38d18906");
  294. base16_decode((char*)spec, sizeof(spec),
  295. "4e61436c" "0A34", 12);
  296. memset(out, 0x00, sizeof(out));
  297. tt_int_op(64, OP_EQ,
  298. secret_to_key_compute_key(out, 64, spec, 6, "password", 8, 2));
  299. test_memeq_hex(out,
  300. "fdbabe1c9d3472007856e7190d01e9fe"
  301. "7c6ad7cbc8237830e77376634b373162"
  302. "2eaf30d92e22a3886ff109279d9830da"
  303. "c727afb94a83ee6d8360cbdfa2cc0640");
  304. base16_decode((char*)spec, sizeof(spec),
  305. "536f6469756d43686c6f72696465" "0e30", 32);
  306. memset(out, 0x00, sizeof(out));
  307. tt_int_op(64, OP_EQ,
  308. secret_to_key_compute_key(out, 64, spec, 16,
  309. "pleaseletmein", 13, 2));
  310. test_memeq_hex(out,
  311. "7023bdcb3afd7348461c06cd81fd38eb"
  312. "fda8fbba904f8e3ea9b543f6545da1f2"
  313. "d5432955613f0fcf62d49705242a9af9"
  314. "e61e85dc0d651e40dfcf017b45575887");
  315. base16_decode((char*)spec, sizeof(spec),
  316. "536f6469756d43686c6f72696465" "1430", 32);
  317. memset(out, 0x00, sizeof(out));
  318. tt_int_op(64, OP_EQ,
  319. secret_to_key_compute_key(out, 64, spec, 16,
  320. "pleaseletmein", 13, 2));
  321. test_memeq_hex(out,
  322. "2101cb9b6a511aaeaddbbe09cf70f881"
  323. "ec568d574a2ffd4dabe5ee9820adaa47"
  324. "8e56fd8f4ba5d09ffa1c6d927c40f4c3"
  325. "37304049e8a952fbcbf45c6fa77a41a4");
  326. done:
  327. tor_free(mem_op_hex_tmp);
  328. }
  329. static void
  330. test_crypto_pbkdf2_vectors(void *arg)
  331. {
  332. char *mem_op_hex_tmp = NULL;
  333. uint8_t spec[64], out[64];
  334. (void)arg;
  335. /* Test vectors from RFC6070, section 2 */
  336. base16_decode((char*)spec, sizeof(spec),
  337. "73616c74" "00" , 10);
  338. memset(out, 0x00, sizeof(out));
  339. tt_int_op(20, OP_EQ,
  340. secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
  341. test_memeq_hex(out, "0c60c80f961f0e71f3a9b524af6012062fe037a6");
  342. base16_decode((char*)spec, sizeof(spec),
  343. "73616c74" "01" , 10);
  344. memset(out, 0x00, sizeof(out));
  345. tt_int_op(20, OP_EQ,
  346. secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
  347. test_memeq_hex(out, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957");
  348. base16_decode((char*)spec, sizeof(spec),
  349. "73616c74" "0C" , 10);
  350. memset(out, 0x00, sizeof(out));
  351. tt_int_op(20, OP_EQ,
  352. secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
  353. test_memeq_hex(out, "4b007901b765489abead49d926f721d065a429c1");
  354. /* This is the very slow one here. When enabled, it accounts for roughly
  355. * half the time spent in test-slow. */
  356. /*
  357. base16_decode((char*)spec, sizeof(spec),
  358. "73616c74" "18" , 10);
  359. memset(out, 0x00, sizeof(out));
  360. tt_int_op(20, OP_EQ,
  361. secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
  362. test_memeq_hex(out, "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984");
  363. */
  364. base16_decode((char*)spec, sizeof(spec),
  365. "73616c7453414c5473616c7453414c5473616c745"
  366. "3414c5473616c7453414c5473616c74" "0C" , 74);
  367. memset(out, 0x00, sizeof(out));
  368. tt_int_op(25, OP_EQ,
  369. secret_to_key_compute_key(out, 25, spec, 37,
  370. "passwordPASSWORDpassword", 24, 1));
  371. test_memeq_hex(out, "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038");
  372. base16_decode((char*)spec, sizeof(spec),
  373. "7361006c74" "0c" , 12);
  374. memset(out, 0x00, sizeof(out));
  375. tt_int_op(16, OP_EQ,
  376. secret_to_key_compute_key(out, 16, spec, 6, "pass\0word", 9, 1));
  377. test_memeq_hex(out, "56fa6aa75548099dcc37d7f03425e0c3");
  378. done:
  379. tor_free(mem_op_hex_tmp);
  380. }
  381. static void
  382. test_crypto_pwbox(void *arg)
  383. {
  384. uint8_t *boxed=NULL, *decoded=NULL;
  385. size_t len, dlen;
  386. unsigned i;
  387. const char msg[] = "This bunny reminds you that you still have a "
  388. "salamander in your sylladex. She is holding the bunny Dave got you. "
  389. "It’s sort of uncanny how similar they are, aside from the knitted "
  390. "enhancements. Seriously, what are the odds?? So weird.";
  391. const char pw[] = "I'm a night owl and a wise bird too";
  392. const unsigned flags[] = { 0,
  393. S2K_FLAG_NO_SCRYPT,
  394. S2K_FLAG_LOW_MEM,
  395. S2K_FLAG_NO_SCRYPT|S2K_FLAG_LOW_MEM,
  396. S2K_FLAG_USE_PBKDF2 };
  397. (void)arg;
  398. for (i = 0; i < ARRAY_LENGTH(flags); ++i) {
  399. tt_int_op(0, OP_EQ, crypto_pwbox(&boxed, &len,
  400. (const uint8_t*)msg, strlen(msg),
  401. pw, strlen(pw), flags[i]));
  402. tt_assert(boxed);
  403. tt_assert(len > 128+32);
  404. tt_int_op(0, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len,
  405. pw, strlen(pw)));
  406. tt_assert(decoded);
  407. tt_uint_op(dlen, OP_EQ, strlen(msg));
  408. tt_mem_op(decoded, OP_EQ, msg, dlen);
  409. tor_free(decoded);
  410. tt_int_op(UNPWBOX_BAD_SECRET, OP_EQ, crypto_unpwbox(&decoded, &dlen,
  411. boxed, len,
  412. pw, strlen(pw)-1));
  413. boxed[len-1] ^= 1;
  414. tt_int_op(UNPWBOX_BAD_SECRET, OP_EQ, crypto_unpwbox(&decoded, &dlen,
  415. boxed, len,
  416. pw, strlen(pw)));
  417. boxed[0] = 255;
  418. tt_int_op(UNPWBOX_CORRUPTED, OP_EQ, crypto_unpwbox(&decoded, &dlen,
  419. boxed, len,
  420. pw, strlen(pw)));
  421. tor_free(boxed);
  422. }
  423. done:
  424. tor_free(boxed);
  425. tor_free(decoded);
  426. }
  427. static void
  428. test_crypto_ed25519_fuzz_donna(void *arg)
  429. {
  430. const unsigned iters = 1024;
  431. uint8_t msg[1024];
  432. unsigned i;
  433. (void)arg;
  434. tt_uint_op(iters, OP_EQ, sizeof(msg));
  435. crypto_rand((char*) msg, sizeof(msg));
  436. /* Fuzz Ed25519-donna vs ref10, alternating the implementation used to
  437. * generate keys/sign per iteration.
  438. */
  439. for (i = 0; i < iters; ++i) {
  440. const int use_donna = i & 1;
  441. uint8_t blinding[32];
  442. curve25519_keypair_t ckp;
  443. ed25519_keypair_t kp, kp_blind, kp_curve25519;
  444. ed25519_public_key_t pk, pk_blind, pk_curve25519;
  445. ed25519_signature_t sig, sig_blind;
  446. int bit = 0;
  447. crypto_rand((char*) blinding, sizeof(blinding));
  448. /* Impl. A:
  449. * 1. Generate a keypair.
  450. * 2. Blinded the keypair.
  451. * 3. Sign a message (unblinded).
  452. * 4. Sign a message (blinded).
  453. * 5. Generate a curve25519 keypair, and convert it to Ed25519.
  454. */
  455. ed25519_set_impl_params(use_donna);
  456. tt_int_op(0, OP_EQ, ed25519_keypair_generate(&kp, i&1));
  457. tt_int_op(0, OP_EQ, ed25519_keypair_blind(&kp_blind, &kp, blinding));
  458. tt_int_op(0, OP_EQ, ed25519_sign(&sig, msg, i, &kp));
  459. tt_int_op(0, OP_EQ, ed25519_sign(&sig_blind, msg, i, &kp_blind));
  460. tt_int_op(0, OP_EQ, curve25519_keypair_generate(&ckp, i&1));
  461. tt_int_op(0, OP_EQ, ed25519_keypair_from_curve25519_keypair(
  462. &kp_curve25519, &bit, &ckp));
  463. /* Impl. B:
  464. * 1. Validate the public key by rederiving it.
  465. * 2. Validate the blinded public key by rederiving it.
  466. * 3. Validate the unblinded signature (and test a invalid signature).
  467. * 4. Validate the blinded signature.
  468. * 5. Validate the public key (from Curve25519) by rederiving it.
  469. */
  470. ed25519_set_impl_params(!use_donna);
  471. tt_int_op(0, OP_EQ, ed25519_public_key_generate(&pk, &kp.seckey));
  472. tt_mem_op(pk.pubkey, OP_EQ, kp.pubkey.pubkey, 32);
  473. tt_int_op(0, OP_EQ, ed25519_public_blind(&pk_blind, &kp.pubkey, blinding));
  474. tt_mem_op(pk_blind.pubkey, OP_EQ, kp_blind.pubkey.pubkey, 32);
  475. tt_int_op(0, OP_EQ, ed25519_checksig(&sig, msg, i, &pk));
  476. sig.sig[0] ^= 15;
  477. tt_int_op(-1, OP_EQ, ed25519_checksig(&sig, msg, sizeof(msg), &pk));
  478. tt_int_op(0, OP_EQ, ed25519_checksig(&sig_blind, msg, i, &pk_blind));
  479. tt_int_op(0, OP_EQ, ed25519_public_key_from_curve25519_public_key(
  480. &pk_curve25519, &ckp.pubkey, bit));
  481. tt_mem_op(pk_curve25519.pubkey, OP_EQ, kp_curve25519.pubkey.pubkey, 32);
  482. }
  483. done:
  484. ;
  485. }
  486. #define CRYPTO_LEGACY(name) \
  487. { #name, test_crypto_ ## name , 0, NULL, NULL }
  488. #define ED25519_TEST_ONE(name, fl, which) \
  489. { #name "/ed25519_" which, test_crypto_ed25519_ ## name, (fl), \
  490. &ed25519_test_setup, (void*)which }
  491. #define ED25519_TEST(name, fl) \
  492. ED25519_TEST_ONE(name, (fl), "donna"), \
  493. ED25519_TEST_ONE(name, (fl), "ref10")
  494. struct testcase_t slow_crypto_tests[] = {
  495. CRYPTO_LEGACY(s2k_rfc2440),
  496. #ifdef HAVE_LIBSCRYPT
  497. { "s2k_scrypt", test_crypto_s2k_general, 0, &passthrough_setup,
  498. (void*)"scrypt" },
  499. { "s2k_scrypt_low", test_crypto_s2k_general, 0, &passthrough_setup,
  500. (void*)"scrypt-low" },
  501. #ifdef HAVE_EVP_PBE_SCRYPT
  502. { "libscrypt_eq_openssl", test_libscrypt_eq_openssl, 0, NULL, NULL },
  503. #endif
  504. #endif /* defined(HAVE_LIBSCRYPT) */
  505. { "s2k_pbkdf2", test_crypto_s2k_general, 0, &passthrough_setup,
  506. (void*)"pbkdf2" },
  507. { "s2k_rfc2440_general", test_crypto_s2k_general, 0, &passthrough_setup,
  508. (void*)"rfc2440" },
  509. { "s2k_rfc2440_legacy", test_crypto_s2k_general, 0, &passthrough_setup,
  510. (void*)"rfc2440-legacy" },
  511. { "s2k_errors", test_crypto_s2k_errors, 0, NULL, NULL },
  512. { "scrypt_vectors", test_crypto_scrypt_vectors, 0, NULL, NULL },
  513. { "pbkdf2_vectors", test_crypto_pbkdf2_vectors, 0, NULL, NULL },
  514. { "pwbox", test_crypto_pwbox, 0, NULL, NULL },
  515. ED25519_TEST(fuzz_donna, TT_FORK),
  516. END_OF_TESTCASES
  517. };