1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
7 #define CRYPTO_S2K_PRIVATE
8 #include "core/or/or.h"
10 #include "ext/equix/include/equix.h"
11 #include "lib/crypt_ops/crypto_curve25519.h"
12 #include "lib/crypt_ops/crypto_ed25519.h"
13 #include "lib/crypt_ops/crypto_s2k.h"
14 #include "lib/crypt_ops/crypto_pwbox.h"
15 #include "lib/crypt_ops/crypto_rand.h"
17 #if defined(HAVE_LIBSCRYPT_H) && defined(HAVE_LIBSCRYPT_SCRYPT)
18 #define HAVE_LIBSCRYPT
19 #include <libscrypt.h>
23 #include <openssl/evp.h>
26 /** Run unit tests for our secret-to-key passphrase hashing functionality. */
28 test_crypto_s2k_rfc2440(void *arg
)
36 memset(buf
, 0, sizeof(buf
));
37 memset(buf2
, 0, sizeof(buf2
));
38 buf3
= tor_malloc(65536);
39 memset(buf3
, 0, 65536);
41 secret_to_key_rfc2440(buf
+9, 20, "", 0, buf
);
42 crypto_digest(buf2
+9, buf3
, 1024);
43 tt_mem_op(buf
,OP_EQ
, buf2
, 29);
45 memcpy(buf
,"vrbacrda",8);
46 memcpy(buf2
,"vrbacrda",8);
49 secret_to_key_rfc2440(buf
+9, 20, "12345678", 8, buf
);
50 for (i
= 0; i
< 65536; i
+= 16) {
51 memcpy(buf3
+i
, "vrbacrda12345678", 16);
53 crypto_digest(buf2
+9, buf3
, 65536);
54 tt_mem_op(buf
,OP_EQ
, buf2
, 29);
61 run_s2k_tests(const unsigned flags
, const unsigned type
,
62 int speclen
, const int keylen
, int legacy
)
64 uint8_t buf
[S2K_MAXLEN
], buf2
[S2K_MAXLEN
], buf3
[S2K_MAXLEN
];
67 const char pw1
[] = "You can't come in here unless you say swordfish!";
68 const char pw2
[] = "Now, I give you one more guess.";
70 r
= secret_to_key_new(buf
, sizeof(buf
), &sz
,
71 pw1
, strlen(pw1
), flags
);
72 tt_int_op(r
, OP_EQ
, S2K_OKAY
);
73 tt_int_op(buf
[0], OP_EQ
, type
);
75 tt_int_op(sz
, OP_EQ
, keylen
+ speclen
);
78 memmove(buf
, buf
+1, sz
-1);
83 tt_int_op(S2K_OKAY
, OP_EQ
,
84 secret_to_key_check(buf
, sz
, pw1
, strlen(pw1
)));
86 tt_int_op(S2K_BAD_SECRET
, OP_EQ
,
87 secret_to_key_check(buf
, sz
, pw2
, strlen(pw2
)));
89 /* Move key to buf2, and clear it. */
90 memset(buf3
, 0, sizeof(buf3
));
91 memcpy(buf2
, buf
+speclen
, keylen
);
92 memset(buf
+speclen
, 0, sz
- speclen
);
94 /* Derivekey should produce the same results. */
95 tt_int_op(S2K_OKAY
, OP_EQ
,
96 secret_to_key_derivekey(buf3
, keylen
, buf
, speclen
, pw1
, strlen(pw1
)));
98 tt_mem_op(buf2
, OP_EQ
, buf3
, keylen
);
100 /* Derivekey with a longer output should fill the output. */
101 memset(buf2
, 0, sizeof(buf2
));
102 tt_int_op(S2K_OKAY
, OP_EQ
,
103 secret_to_key_derivekey(buf2
, sizeof(buf2
), buf
, speclen
,
106 tt_mem_op(buf2
, OP_NE
, buf3
, sizeof(buf2
));
108 memset(buf3
, 0, sizeof(buf3
));
109 tt_int_op(S2K_OKAY
, OP_EQ
,
110 secret_to_key_derivekey(buf3
, sizeof(buf3
), buf
, speclen
,
112 tt_mem_op(buf2
, OP_EQ
, buf3
, sizeof(buf3
));
113 tt_assert(!fast_mem_is_zero((char*)buf2
+keylen
, sizeof(buf2
)-keylen
));
120 test_crypto_s2k_general(void *arg
)
122 const char *which
= arg
;
124 if (!strcmp(which
, "scrypt")) {
125 run_s2k_tests(0, 2, 19, 32, 0);
126 } else if (!strcmp(which
, "scrypt-low")) {
127 run_s2k_tests(S2K_FLAG_LOW_MEM
, 2, 19, 32, 0);
128 } else if (!strcmp(which
, "pbkdf2")) {
129 run_s2k_tests(S2K_FLAG_USE_PBKDF2
, 1, 18, 20, 0);
130 } else if (!strcmp(which
, "rfc2440")) {
131 run_s2k_tests(S2K_FLAG_NO_SCRYPT
, 0, 10, 20, 0);
132 } else if (!strcmp(which
, "rfc2440-legacy")) {
133 run_s2k_tests(S2K_FLAG_NO_SCRYPT
, 0, 10, 20, 1);
139 #if defined(HAVE_LIBSCRYPT) && defined(HAVE_EVP_PBE_SCRYPT)
141 test_libscrypt_eq_openssl(void *arg
)
148 uint64_t maxmem
= 0; // --> SCRYPT_MAX_MEM in OpenSSL.
150 int libscrypt_retval
, openssl_retval
;
159 /* NOTE: we're using N,r the way OpenSSL and libscrypt define them,
160 * not the way draft-josefsson-scrypt-kdf-00.txt define them.
167 libscrypt_scrypt((const uint8_t *)"", 0, (const uint8_t *)"", 0,
168 N
, r
, p
, buf1
, dk_len
);
170 EVP_PBE_scrypt((const char *)"", 0, (const unsigned char *)"", 0,
171 N
, r
, p
, maxmem
, buf2
, dk_len
);
173 tt_int_op(libscrypt_retval
, OP_EQ
, 0);
174 tt_int_op(openssl_retval
, OP_EQ
, 1);
176 tt_mem_op(buf1
, OP_EQ
, buf2
, 64);
186 libscrypt_scrypt((const uint8_t *)"password", strlen("password"),
187 (const uint8_t *)"NaCl", strlen("NaCl"),
188 N
, r
, p
, buf1
, dk_len
);
190 EVP_PBE_scrypt((const char *)"password", strlen("password"),
191 (const unsigned char *)"NaCl", strlen("NaCl"),
192 N
, r
, p
, maxmem
, buf2
, dk_len
);
194 tt_int_op(libscrypt_retval
, OP_EQ
, 0);
195 tt_int_op(openssl_retval
, OP_EQ
, 1);
197 tt_mem_op(buf1
, OP_EQ
, buf2
, 64);
207 libscrypt_scrypt((const uint8_t *)"pleaseletmein",
208 strlen("pleaseletmein"),
209 (const uint8_t *)"SodiumChloride",
210 strlen("SodiumChloride"),
211 N
, r
, p
, buf1
, dk_len
);
213 EVP_PBE_scrypt((const char *)"pleaseletmein",
214 strlen("pleaseletmein"),
215 (const unsigned char *)"SodiumChloride",
216 strlen("SodiumChloride"),
217 N
, r
, p
, maxmem
, buf2
, dk_len
);
219 tt_int_op(libscrypt_retval
, OP_EQ
, 0);
220 tt_int_op(openssl_retval
, OP_EQ
, 1);
222 tt_mem_op(buf1
, OP_EQ
, buf2
, 64);
228 maxmem
= 2 * 1024 * 1024 * (uint64_t)1024; // 2 GB
231 libscrypt_scrypt((const uint8_t *)"pleaseletmein",
232 strlen("pleaseletmein"),
233 (const uint8_t *)"SodiumChloride",
234 strlen("SodiumChloride"),
235 N
, r
, p
, buf1
, dk_len
);
237 EVP_PBE_scrypt((const char *)"pleaseletmein",
238 strlen("pleaseletmein"),
239 (const unsigned char *)"SodiumChloride",
240 strlen("SodiumChloride"),
241 N
, r
, p
, maxmem
, buf2
, dk_len
);
243 tt_int_op(libscrypt_retval
, OP_EQ
, 0);
244 tt_int_op(openssl_retval
, OP_EQ
, 1);
246 tt_mem_op(buf1
, OP_EQ
, buf2
, 64);
251 #endif /* defined(HAVE_LIBSCRYPT) && defined(HAVE_EVP_PBE_SCRYPT) */
254 test_crypto_s2k_errors(void *arg
)
256 uint8_t buf
[S2K_MAXLEN
], buf2
[S2K_MAXLEN
];
261 /* Bogus specifiers: simple */
262 tt_int_op(S2K_BAD_LEN
, OP_EQ
,
263 secret_to_key_derivekey(buf
, sizeof(buf
),
264 (const uint8_t*)"", 0, "ABC", 3));
265 tt_int_op(S2K_BAD_ALGORITHM
, OP_EQ
,
266 secret_to_key_derivekey(buf
, sizeof(buf
),
267 (const uint8_t*)"\x10", 1, "ABC", 3));
268 tt_int_op(S2K_BAD_LEN
, OP_EQ
,
269 secret_to_key_derivekey(buf
, sizeof(buf
),
270 (const uint8_t*)"\x01\x02", 2, "ABC", 3));
272 tt_int_op(S2K_BAD_LEN
, OP_EQ
,
273 secret_to_key_check((const uint8_t*)"", 0, "ABC", 3));
274 tt_int_op(S2K_BAD_ALGORITHM
, OP_EQ
,
275 secret_to_key_check((const uint8_t*)"\x10", 1, "ABC", 3));
276 tt_int_op(S2K_BAD_LEN
, OP_EQ
,
277 secret_to_key_check((const uint8_t*)"\x01\x02", 2, "ABC", 3));
279 /* too long gets "BAD_LEN" too */
280 memset(buf
, 0, sizeof(buf
));
282 tt_int_op(S2K_BAD_LEN
, OP_EQ
,
283 secret_to_key_derivekey(buf2
, sizeof(buf2
),
284 buf
, sizeof(buf
), "ABC", 3));
286 /* Truncated output */
287 #ifdef HAVE_LIBSCRYPT
288 tt_int_op(S2K_TRUNCATED
, OP_EQ
, secret_to_key_new(buf
, 50, &sz
,
290 tt_int_op(S2K_TRUNCATED
, OP_EQ
, secret_to_key_new(buf
, 50, &sz
,
291 "ABC", 3, S2K_FLAG_LOW_MEM
));
292 #endif /* defined(HAVE_LIBSCRYPT) */
293 tt_int_op(S2K_TRUNCATED
, OP_EQ
, secret_to_key_new(buf
, 37, &sz
,
294 "ABC", 3, S2K_FLAG_USE_PBKDF2
));
295 tt_int_op(S2K_TRUNCATED
, OP_EQ
, secret_to_key_new(buf
, 29, &sz
,
296 "ABC", 3, S2K_FLAG_NO_SCRYPT
));
298 #ifdef HAVE_LIBSCRYPT
299 tt_int_op(S2K_TRUNCATED
, OP_EQ
, secret_to_key_make_specifier(buf
, 18, 0));
300 tt_int_op(S2K_TRUNCATED
, OP_EQ
, secret_to_key_make_specifier(buf
, 18,
303 tt_int_op(S2K_TRUNCATED
, OP_EQ
, secret_to_key_make_specifier(buf
, 17,
304 S2K_FLAG_USE_PBKDF2
));
305 tt_int_op(S2K_TRUNCATED
, OP_EQ
, secret_to_key_make_specifier(buf
, 9,
306 S2K_FLAG_NO_SCRYPT
));
308 /* Now try using type-specific bogus specifiers. */
310 /* It's a bad pbkdf2 buffer if it has an iteration count that would overflow
312 memset(buf
, 0, sizeof(buf
));
313 buf
[0] = 1; /* pbkdf2 */
314 buf
[17] = 100; /* 1<<100 is much bigger than INT32_MAX */
315 tt_int_op(S2K_BAD_PARAMS
, OP_EQ
,
316 secret_to_key_derivekey(buf2
, sizeof(buf2
),
319 #ifdef HAVE_LIBSCRYPT
320 /* It's a bad scrypt buffer if N would overflow uint64 */
321 memset(buf
, 0, sizeof(buf
));
322 buf
[0] = 2; /* scrypt */
323 buf
[17] = 100; /* 1<<100 is much bigger than UINT64_MAX */
324 tt_int_op(S2K_BAD_PARAMS
, OP_EQ
,
325 secret_to_key_derivekey(buf2
, sizeof(buf2
),
327 #endif /* defined(HAVE_LIBSCRYPT) */
334 test_crypto_scrypt_vectors(void *arg
)
336 char *mem_op_hex_tmp
= NULL
;
337 uint8_t spec
[64], out
[64];
340 #ifndef HAVE_LIBSCRYPT
346 https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-00 section 11.
348 Note that the names of 'r' and 'N' are switched in that section. Or
349 possibly in libscrypt.
352 base16_decode((char*)spec
, sizeof(spec
),
354 memset(out
, 0x00, sizeof(out
));
356 secret_to_key_compute_key(out
, 64, spec
, 2, "", 0, 2));
358 "77d6576238657b203b19ca42c18a0497"
359 "f16b4844e3074ae8dfdffa3fede21442"
360 "fcd0069ded0948f8326a753a0fc81f17"
361 "e8d3e0fb2e0d3628cf35e20c38d18906");
363 base16_decode((char*)spec
, sizeof(spec
),
364 "4e61436c" "0A34", 12);
365 memset(out
, 0x00, sizeof(out
));
367 secret_to_key_compute_key(out
, 64, spec
, 6, "password", 8, 2));
369 "fdbabe1c9d3472007856e7190d01e9fe"
370 "7c6ad7cbc8237830e77376634b373162"
371 "2eaf30d92e22a3886ff109279d9830da"
372 "c727afb94a83ee6d8360cbdfa2cc0640");
374 base16_decode((char*)spec
, sizeof(spec
),
375 "536f6469756d43686c6f72696465" "0e30", 32);
376 memset(out
, 0x00, sizeof(out
));
378 secret_to_key_compute_key(out
, 64, spec
, 16,
379 "pleaseletmein", 13, 2));
381 "7023bdcb3afd7348461c06cd81fd38eb"
382 "fda8fbba904f8e3ea9b543f6545da1f2"
383 "d5432955613f0fcf62d49705242a9af9"
384 "e61e85dc0d651e40dfcf017b45575887");
386 base16_decode((char*)spec
, sizeof(spec
),
387 "536f6469756d43686c6f72696465" "1430", 32);
388 memset(out
, 0x00, sizeof(out
));
390 secret_to_key_compute_key(out
, 64, spec
, 16,
391 "pleaseletmein", 13, 2));
393 "2101cb9b6a511aaeaddbbe09cf70f881"
394 "ec568d574a2ffd4dabe5ee9820adaa47"
395 "8e56fd8f4ba5d09ffa1c6d927c40f4c3"
396 "37304049e8a952fbcbf45c6fa77a41a4");
399 tor_free(mem_op_hex_tmp
);
403 test_crypto_pbkdf2_vectors(void *arg
)
405 char *mem_op_hex_tmp
= NULL
;
406 uint8_t spec
[64], out
[64];
409 /* Test vectors from RFC6070, section 2 */
410 base16_decode((char*)spec
, sizeof(spec
),
411 "73616c74" "00" , 10);
412 memset(out
, 0x00, sizeof(out
));
414 secret_to_key_compute_key(out
, 20, spec
, 5, "password", 8, 1));
415 test_memeq_hex(out
, "0c60c80f961f0e71f3a9b524af6012062fe037a6");
417 base16_decode((char*)spec
, sizeof(spec
),
418 "73616c74" "01" , 10);
419 memset(out
, 0x00, sizeof(out
));
421 secret_to_key_compute_key(out
, 20, spec
, 5, "password", 8, 1));
422 test_memeq_hex(out
, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957");
424 base16_decode((char*)spec
, sizeof(spec
),
425 "73616c74" "0C" , 10);
426 memset(out
, 0x00, sizeof(out
));
428 secret_to_key_compute_key(out
, 20, spec
, 5, "password", 8, 1));
429 test_memeq_hex(out
, "4b007901b765489abead49d926f721d065a429c1");
431 /* This is the very slow one here. When enabled, it accounts for roughly
432 * half the time spent in test-slow. */
434 base16_decode((char*)spec, sizeof(spec),
435 "73616c74" "18" , 10);
436 memset(out, 0x00, sizeof(out));
438 secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
439 test_memeq_hex(out, "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984");
442 base16_decode((char*)spec
, sizeof(spec
),
443 "73616c7453414c5473616c7453414c5473616c745"
444 "3414c5473616c7453414c5473616c74" "0C" , 74);
445 memset(out
, 0x00, sizeof(out
));
447 secret_to_key_compute_key(out
, 25, spec
, 37,
448 "passwordPASSWORDpassword", 24, 1));
449 test_memeq_hex(out
, "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038");
451 base16_decode((char*)spec
, sizeof(spec
),
452 "7361006c74" "0c" , 12);
453 memset(out
, 0x00, sizeof(out
));
455 secret_to_key_compute_key(out
, 16, spec
, 6, "pass\0word", 9, 1));
456 test_memeq_hex(out
, "56fa6aa75548099dcc37d7f03425e0c3");
459 tor_free(mem_op_hex_tmp
);
463 test_crypto_pwbox(void *arg
)
465 uint8_t *boxed
=NULL
, *decoded
=NULL
;
468 const char msg
[] = "This bunny reminds you that you still have a "
469 "salamander in your sylladex. She is holding the bunny Dave got you. "
470 "It’s sort of uncanny how similar they are, aside from the knitted "
471 "enhancements. Seriously, what are the odds?? So weird.";
472 const char pw
[] = "I'm a night owl and a wise bird too";
474 const unsigned flags
[] = { 0,
477 S2K_FLAG_NO_SCRYPT
|S2K_FLAG_LOW_MEM
,
478 S2K_FLAG_USE_PBKDF2
};
481 for (i
= 0; i
< ARRAY_LENGTH(flags
); ++i
) {
482 tt_int_op(0, OP_EQ
, crypto_pwbox(&boxed
, &len
,
483 (const uint8_t*)msg
, strlen(msg
),
484 pw
, strlen(pw
), flags
[i
]));
486 tt_assert(len
> 128+32);
488 tt_int_op(0, OP_EQ
, crypto_unpwbox(&decoded
, &dlen
, boxed
, len
,
492 tt_uint_op(dlen
, OP_EQ
, strlen(msg
));
493 tt_mem_op(decoded
, OP_EQ
, msg
, dlen
);
497 tt_int_op(UNPWBOX_BAD_SECRET
, OP_EQ
, crypto_unpwbox(&decoded
, &dlen
,
501 tt_int_op(UNPWBOX_BAD_SECRET
, OP_EQ
, crypto_unpwbox(&decoded
, &dlen
,
505 tt_int_op(UNPWBOX_CORRUPTED
, OP_EQ
, crypto_unpwbox(&decoded
, &dlen
,
518 test_crypto_ed25519_fuzz_donna(void *arg
)
520 const unsigned iters
= 1024;
525 tt_uint_op(iters
, OP_EQ
, sizeof(msg
));
526 crypto_rand((char*) msg
, sizeof(msg
));
528 /* Fuzz Ed25519-donna vs ref10, alternating the implementation used to
529 * generate keys/sign per iteration.
531 for (i
= 0; i
< iters
; ++i
) {
532 const int use_donna
= i
& 1;
533 uint8_t blinding
[32];
534 curve25519_keypair_t ckp
;
535 ed25519_keypair_t kp
, kp_blind
, kp_curve25519
;
536 ed25519_public_key_t pk
, pk_blind
, pk_curve25519
;
537 ed25519_signature_t sig
, sig_blind
;
540 crypto_rand((char*) blinding
, sizeof(blinding
));
543 * 1. Generate a keypair.
544 * 2. Blinded the keypair.
545 * 3. Sign a message (unblinded).
546 * 4. Sign a message (blinded).
547 * 5. Generate a curve25519 keypair, and convert it to Ed25519.
549 ed25519_set_impl_params(use_donna
);
550 tt_int_op(0, OP_EQ
, ed25519_keypair_generate(&kp
, i
&1));
551 tt_int_op(0, OP_EQ
, ed25519_keypair_blind(&kp_blind
, &kp
, blinding
));
552 tt_int_op(0, OP_EQ
, ed25519_sign(&sig
, msg
, i
, &kp
));
553 tt_int_op(0, OP_EQ
, ed25519_sign(&sig_blind
, msg
, i
, &kp_blind
));
555 tt_int_op(0, OP_EQ
, curve25519_keypair_generate(&ckp
, i
&1));
556 tt_int_op(0, OP_EQ
, ed25519_keypair_from_curve25519_keypair(
557 &kp_curve25519
, &bit
, &ckp
));
560 * 1. Validate the public key by rederiving it.
561 * 2. Validate the blinded public key by rederiving it.
562 * 3. Validate the unblinded signature (and test a invalid signature).
563 * 4. Validate the blinded signature.
564 * 5. Validate the public key (from Curve25519) by rederiving it.
566 ed25519_set_impl_params(!use_donna
);
567 tt_int_op(0, OP_EQ
, ed25519_public_key_generate(&pk
, &kp
.seckey
));
568 tt_mem_op(pk
.pubkey
, OP_EQ
, kp
.pubkey
.pubkey
, 32);
570 tt_int_op(0, OP_EQ
, ed25519_public_blind(&pk_blind
, &kp
.pubkey
, blinding
));
571 tt_mem_op(pk_blind
.pubkey
, OP_EQ
, kp_blind
.pubkey
.pubkey
, 32);
573 tt_int_op(0, OP_EQ
, ed25519_checksig(&sig
, msg
, i
, &pk
));
575 tt_int_op(-1, OP_EQ
, ed25519_checksig(&sig
, msg
, sizeof(msg
), &pk
));
577 tt_int_op(0, OP_EQ
, ed25519_checksig(&sig_blind
, msg
, i
, &pk_blind
));
579 tt_int_op(0, OP_EQ
, ed25519_public_key_from_curve25519_public_key(
580 &pk_curve25519
, &ckp
.pubkey
, bit
));
581 tt_mem_op(pk_curve25519
.pubkey
, OP_EQ
, kp_curve25519
.pubkey
.pubkey
, 32);
589 test_crypto_equix(void *arg
)
593 static const struct {
594 const char *challenge_literal
;
595 size_t num_solutions
;
596 equix_solution solutions
[EQUIX_MAX_SOLS
];
599 {{ 0xae21, 0xd392, 0x3215, 0xdd9c, 0x2f08, 0x93df, 0x232c, 0xe5dc }},
602 {{ 0x0873, 0x57a8, 0x73e0, 0x912e, 0x1ca8, 0xad96, 0x9abd, 0xd7de }},
604 { "qqq", 0, {{{ 0 }}} },
605 { "0123456789", 0, {{{ 0 }}} },
606 { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0, {{{ 0 }}} },
608 {{ 0x0098, 0x3a4d, 0xc489, 0xcfba, 0x7ef3, 0xa498, 0xa00f, 0xec20 }},
609 {{ 0x78d8, 0x8611, 0xa4df, 0xec19, 0x0927, 0xa729, 0x842f, 0xf771 }},
610 {{ 0x54b5, 0xcc11, 0x1593, 0xe624, 0x9357, 0xb339, 0xb138, 0xed99 }},
613 {{ 0x4b38, 0x8c81, 0x9255, 0xad99, 0x5ce7, 0xeb3e, 0xc635, 0xee38 }},
614 {{ 0x3f9e, 0x659b, 0x9ae6, 0xb891, 0x63ae, 0x777c, 0x06ca, 0xc593 }},
615 {{ 0x2227, 0xa173, 0x365a, 0xb47d, 0x1bb2, 0xa077, 0x0d5e, 0xf25f }},
618 {{ 0x371f, 0x8865, 0x8189, 0xfbc3, 0x26df, 0xe4c0, 0xab39, 0xfe5a }},
619 {{ 0x2101, 0xb88f, 0xc525, 0xccb3, 0x5785, 0xa41e, 0x4fba, 0xed18 }},
622 {{ 0x4fca, 0x72eb, 0x101f, 0xafab, 0x1add, 0x2d71, 0x75a3, 0xc978 }},
623 {{ 0x17f1, 0x7aa6, 0x23e3, 0xab00, 0x7e2f, 0x917e, 0x16da, 0xda9e }},
624 {{ 0x70ee, 0x7757, 0x8a54, 0xbd2b, 0x90e4, 0xe31e, 0x2085, 0xe47e }},
625 {{ 0x62c5, 0x86d1, 0x5752, 0xe1f0, 0x12da, 0x8f33, 0x7336, 0xf161 }},
627 { "01234567890123456789", 5, {
628 {{ 0x4803, 0x6775, 0xc5c9, 0xd1b0, 0x1bc3, 0xe4f6, 0x4027, 0xf5ad }},
629 {{ 0x5a8a, 0x9542, 0xef99, 0xf0b9, 0x4905, 0x4e29, 0x2da5, 0xfbd5 }},
630 {{ 0x4c79, 0xc935, 0x2bcb, 0xcd0f, 0x0362, 0x9fa9, 0xa62e, 0xf83a }},
631 {{ 0x5878, 0x6edf, 0x1e00, 0xf5e3, 0x43de, 0x9212, 0xd01e, 0xfd11 }},
632 {{ 0x0b69, 0x2d17, 0x01be, 0x6cb4, 0x0fba, 0x4a9e, 0x8d75, 0xa50f }},
636 static const struct {
637 equix_ctx_flags flags
;
638 equix_result expected
;
639 equix_solution_flags sol_flags
;
642 {0, EQUIX_FAIL_ORDER
, 0},
643 {0, EQUIX_FAIL_PARTIAL_SUM
, 0},
644 #if defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__)
645 { EQUIX_CTX_MUST_COMPILE
, EQUIX_OK
,
646 EQUIX_SOLVER_DID_USE_COMPILER
648 { EQUIX_CTX_MUST_COMPILE
, EQUIX_FAIL_ORDER
,
649 EQUIX_SOLVER_DID_USE_COMPILER
651 { EQUIX_CTX_MUST_COMPILE
, EQUIX_FAIL_PARTIAL_SUM
,
652 EQUIX_SOLVER_DID_USE_COMPILER
657 const unsigned num_vectors
= sizeof vectors
/ sizeof vectors
[0];
658 const unsigned num_variations
= sizeof variations
/ sizeof variations
[0];
660 for (unsigned vec_i
= 0; vec_i
< num_vectors
; vec_i
++) {
661 const char *challenge_literal
= vectors
[vec_i
].challenge_literal
;
662 const size_t challenge_len
= strlen(challenge_literal
);
664 const size_t num_sols
= vectors
[vec_i
].num_solutions
;
665 const equix_solution
*sols_expected
= vectors
[vec_i
].solutions
;
667 for (unsigned vari_i
= 0; vari_i
< num_variations
; vari_i
++) {
668 const equix_ctx_flags flags
= variations
[vari_i
].flags
;
669 const equix_solution_flags sol_flags
= variations
[vari_i
].sol_flags
;
670 const equix_result expected
= variations
[vari_i
].expected
;
672 equix_solutions_buffer output
;
673 equix_ctx
*solve_ctx
= NULL
, *verify_ctx
= NULL
;
675 solve_ctx
= equix_alloc(EQUIX_CTX_SOLVE
| flags
);
676 tt_ptr_op(solve_ctx
, OP_NE
, NULL
);
678 /* Solve phase: Make sure the test vector matches */
679 memset(&output
, 0xa5, sizeof output
);
681 result
= equix_solve(solve_ctx
, challenge_literal
,
682 challenge_len
, &output
);
683 equix_free(solve_ctx
);
684 tt_int_op(result
, OP_EQ
, EQUIX_OK
);
685 tt_int_op(output
.count
, OP_EQ
, num_sols
);
686 tt_int_op(output
.flags
, OP_EQ
, sol_flags
);
687 tt_mem_op(output
.sols
, OP_EQ
, sols_expected
,
688 num_sols
* sizeof(equix_solution
));
690 verify_ctx
= equix_alloc(EQUIX_CTX_VERIFY
| flags
);
691 tt_ptr_op(verify_ctx
, OP_NE
, NULL
);
693 /* Use each solution for positive and negative tests of verify */
694 for (size_t sol_i
= 0; sol_i
< num_sols
; sol_i
++) {
696 equix_solution
*sol
= &output
.sols
[sol_i
];
698 if (expected
== EQUIX_FAIL_ORDER
) {
699 /* Swap two otherwise valid indices, to trigger an order error */
700 tmp_idx
= sol
->idx
[0];
701 sol
->idx
[0] = sol
->idx
[1];
702 sol
->idx
[1] = tmp_idx
;
703 } else if (expected
== EQUIX_FAIL_PARTIAL_SUM
) {
704 /* Most changes to the solution will cause a partial sum error */
708 result
= equix_verify(verify_ctx
, challenge_literal
,
710 tt_int_op(expected
, OP_EQ
, result
);
713 equix_free(verify_ctx
);
722 #define CRYPTO_LEGACY(name) \
723 { #name, test_crypto_ ## name , 0, NULL, NULL }
725 #define ED25519_TEST_ONE(name, fl, which) \
726 { #name "/ed25519_" which, test_crypto_ed25519_ ## name, (fl), \
727 &ed25519_test_setup, (void*)which }
729 #define ED25519_TEST(name, fl) \
730 ED25519_TEST_ONE(name, (fl), "donna"), \
731 ED25519_TEST_ONE(name, (fl), "ref10")
732 #endif /* !defined(COCCI) */
734 struct testcase_t slow_crypto_tests
[] = {
735 CRYPTO_LEGACY(s2k_rfc2440
),
736 #ifdef HAVE_LIBSCRYPT
737 { "s2k_scrypt", test_crypto_s2k_general
, 0, &passthrough_setup
,
739 { "s2k_scrypt_low", test_crypto_s2k_general
, 0, &passthrough_setup
,
740 (void*)"scrypt-low" },
741 #ifdef HAVE_EVP_PBE_SCRYPT
742 { "libscrypt_eq_openssl", test_libscrypt_eq_openssl
, 0, NULL
, NULL
},
744 #endif /* defined(HAVE_LIBSCRYPT) */
745 { "s2k_pbkdf2", test_crypto_s2k_general
, 0, &passthrough_setup
,
747 { "s2k_rfc2440_general", test_crypto_s2k_general
, 0, &passthrough_setup
,
749 { "s2k_rfc2440_legacy", test_crypto_s2k_general
, 0, &passthrough_setup
,
750 (void*)"rfc2440-legacy" },
751 { "s2k_errors", test_crypto_s2k_errors
, 0, NULL
, NULL
},
752 { "scrypt_vectors", test_crypto_scrypt_vectors
, 0, NULL
, NULL
},
753 { "pbkdf2_vectors", test_crypto_pbkdf2_vectors
, 0, NULL
, NULL
},
754 { "pwbox", test_crypto_pwbox
, 0, NULL
, NULL
},
755 ED25519_TEST(fuzz_donna
, TT_FORK
),
756 { "equix", test_crypto_equix
, 0, NULL
, NULL
},