test_crypto_slow.c 16 KB

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