test_crypto_slow.c 14 KB

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