test_crypto_slow.c (25528B)
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 */ 5 6 #include "orconfig.h" 7 #define CRYPTO_S2K_PRIVATE 8 #include "core/or/or.h" 9 #include "test/test.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" 16 17 #if defined(HAVE_LIBSCRYPT_H) && defined(HAVE_LIBSCRYPT_SCRYPT) 18 #define HAVE_LIBSCRYPT 19 #include <libscrypt.h> 20 #endif 21 22 #ifdef ENABLE_OPENSSL 23 #include <openssl/evp.h> 24 #endif 25 26 /** Run unit tests for our secret-to-key passphrase hashing functionality. */ 27 static void 28 test_crypto_s2k_rfc2440(void *arg) 29 { 30 char buf[29]; 31 char buf2[29]; 32 char *buf3 = NULL; 33 int i; 34 35 (void)arg; 36 memset(buf, 0, sizeof(buf)); 37 memset(buf2, 0, sizeof(buf2)); 38 buf3 = tor_malloc(65536); 39 memset(buf3, 0, 65536); 40 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); 44 45 memcpy(buf,"vrbacrda",8); 46 memcpy(buf2,"vrbacrda",8); 47 buf[8] = 96; 48 buf2[8] = 96; 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); 52 } 53 crypto_digest(buf2+9, buf3, 65536); 54 tt_mem_op(buf,OP_EQ, buf2, 29); 55 56 done: 57 tor_free(buf3); 58 } 59 60 static void 61 run_s2k_tests(const unsigned flags, const unsigned type, 62 int speclen, const int keylen, int legacy) 63 { 64 uint8_t buf[S2K_MAXLEN], buf2[S2K_MAXLEN], buf3[S2K_MAXLEN]; 65 int r; 66 size_t sz; 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."; 69 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); 74 75 tt_int_op(sz, OP_EQ, keylen + speclen); 76 77 if (legacy) { 78 memmove(buf, buf+1, sz-1); 79 --sz; 80 --speclen; 81 } 82 83 tt_int_op(S2K_OKAY, OP_EQ, 84 secret_to_key_check(buf, sz, pw1, strlen(pw1))); 85 86 tt_int_op(S2K_BAD_SECRET, OP_EQ, 87 secret_to_key_check(buf, sz, pw2, strlen(pw2))); 88 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); 93 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))); 97 98 tt_mem_op(buf2, OP_EQ, buf3, keylen); 99 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, 104 pw1, strlen(pw1))); 105 106 tt_mem_op(buf2, OP_NE, buf3, sizeof(buf2)); 107 108 memset(buf3, 0, sizeof(buf3)); 109 tt_int_op(S2K_OKAY, OP_EQ, 110 secret_to_key_derivekey(buf3, sizeof(buf3), buf, speclen, 111 pw1, strlen(pw1))); 112 tt_mem_op(buf2, OP_EQ, buf3, sizeof(buf3)); 113 tt_assert(!fast_mem_is_zero((char*)buf2+keylen, sizeof(buf2)-keylen)); 114 115 done: 116 ; 117 } 118 119 static void 120 test_crypto_s2k_general(void *arg) 121 { 122 const char *which = arg; 123 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); 134 } else { 135 tt_fail(); 136 } 137 } 138 139 #if defined(HAVE_LIBSCRYPT) && defined(HAVE_EVP_PBE_SCRYPT) 140 static void 141 test_libscrypt_eq_openssl(void *arg) 142 { 143 uint8_t buf1[64]; 144 uint8_t buf2[64]; 145 146 uint64_t N; 147 uint32_t r, p; 148 uint64_t maxmem = 0; // --> SCRYPT_MAX_MEM in OpenSSL. 149 150 int libscrypt_retval, openssl_retval; 151 152 size_t dk_len = 64; 153 154 (void)arg; 155 156 memset(buf1,0,64); 157 memset(buf2,0,64); 158 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. 161 */ 162 N = 16; 163 r = 1; 164 p = 1; 165 166 libscrypt_retval = 167 libscrypt_scrypt((const uint8_t *)"", 0, (const uint8_t *)"", 0, 168 N, r, p, buf1, dk_len); 169 openssl_retval = 170 EVP_PBE_scrypt((const char *)"", 0, (const unsigned char *)"", 0, 171 N, r, p, maxmem, buf2, dk_len); 172 173 tt_int_op(libscrypt_retval, OP_EQ, 0); 174 tt_int_op(openssl_retval, OP_EQ, 1); 175 176 tt_mem_op(buf1, OP_EQ, buf2, 64); 177 178 memset(buf1,0,64); 179 memset(buf2,0,64); 180 181 N = 1024; 182 r = 8; 183 p = 16; 184 185 libscrypt_retval = 186 libscrypt_scrypt((const uint8_t *)"password", strlen("password"), 187 (const uint8_t *)"NaCl", strlen("NaCl"), 188 N, r, p, buf1, dk_len); 189 openssl_retval = 190 EVP_PBE_scrypt((const char *)"password", strlen("password"), 191 (const unsigned char *)"NaCl", strlen("NaCl"), 192 N, r, p, maxmem, buf2, dk_len); 193 194 tt_int_op(libscrypt_retval, OP_EQ, 0); 195 tt_int_op(openssl_retval, OP_EQ, 1); 196 197 tt_mem_op(buf1, OP_EQ, buf2, 64); 198 199 memset(buf1,0,64); 200 memset(buf2,0,64); 201 202 N = 16384; 203 r = 8; 204 p = 1; 205 206 libscrypt_retval = 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); 212 openssl_retval = 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); 218 219 tt_int_op(libscrypt_retval, OP_EQ, 0); 220 tt_int_op(openssl_retval, OP_EQ, 1); 221 222 tt_mem_op(buf1, OP_EQ, buf2, 64); 223 224 memset(buf1,0,64); 225 memset(buf2,0,64); 226 227 N = 1048576; 228 maxmem = 2 * 1024 * 1024 * (uint64_t)1024; // 2 GB 229 230 libscrypt_retval = 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); 236 openssl_retval = 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); 242 243 tt_int_op(libscrypt_retval, OP_EQ, 0); 244 tt_int_op(openssl_retval, OP_EQ, 1); 245 246 tt_mem_op(buf1, OP_EQ, buf2, 64); 247 248 done: 249 return; 250 } 251 #endif /* defined(HAVE_LIBSCRYPT) && defined(HAVE_EVP_PBE_SCRYPT) */ 252 253 static void 254 test_crypto_s2k_errors(void *arg) 255 { 256 uint8_t buf[S2K_MAXLEN], buf2[S2K_MAXLEN]; 257 size_t sz; 258 259 (void)arg; 260 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)); 271 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)); 278 279 /* too long gets "BAD_LEN" too */ 280 memset(buf, 0, sizeof(buf)); 281 buf[0] = 2; 282 tt_int_op(S2K_BAD_LEN, OP_EQ, 283 secret_to_key_derivekey(buf2, sizeof(buf2), 284 buf, sizeof(buf), "ABC", 3)); 285 286 /* Truncated output */ 287 #ifdef HAVE_LIBSCRYPT 288 tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_new(buf, 50, &sz, 289 "ABC", 3, 0)); 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)); 297 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, 301 S2K_FLAG_LOW_MEM)); 302 #endif 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)); 307 308 /* Now try using type-specific bogus specifiers. */ 309 310 /* It's a bad pbkdf2 buffer if it has an iteration count that would overflow 311 * int32_t. */ 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), 317 buf, 18, "ABC", 3)); 318 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), 326 buf, 19, "ABC", 3)); 327 #endif /* defined(HAVE_LIBSCRYPT) */ 328 329 done: 330 ; 331 } 332 333 static void 334 test_crypto_scrypt_vectors(void *arg) 335 { 336 char *mem_op_hex_tmp = NULL; 337 uint8_t spec[64], out[64]; 338 339 (void)arg; 340 #ifndef HAVE_LIBSCRYPT 341 if (1) 342 tt_skip(); 343 #endif 344 345 /* Test vectors from 346 https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-00 section 11. 347 348 Note that the names of 'r' and 'N' are switched in that section. Or 349 possibly in libscrypt. 350 */ 351 352 base16_decode((char*)spec, sizeof(spec), 353 "0400", 4); 354 memset(out, 0x00, sizeof(out)); 355 tt_int_op(64, OP_EQ, 356 secret_to_key_compute_key(out, 64, spec, 2, "", 0, 2)); 357 test_memeq_hex(out, 358 "77d6576238657b203b19ca42c18a0497" 359 "f16b4844e3074ae8dfdffa3fede21442" 360 "fcd0069ded0948f8326a753a0fc81f17" 361 "e8d3e0fb2e0d3628cf35e20c38d18906"); 362 363 base16_decode((char*)spec, sizeof(spec), 364 "4e61436c" "0A34", 12); 365 memset(out, 0x00, sizeof(out)); 366 tt_int_op(64, OP_EQ, 367 secret_to_key_compute_key(out, 64, spec, 6, "password", 8, 2)); 368 test_memeq_hex(out, 369 "fdbabe1c9d3472007856e7190d01e9fe" 370 "7c6ad7cbc8237830e77376634b373162" 371 "2eaf30d92e22a3886ff109279d9830da" 372 "c727afb94a83ee6d8360cbdfa2cc0640"); 373 374 base16_decode((char*)spec, sizeof(spec), 375 "536f6469756d43686c6f72696465" "0e30", 32); 376 memset(out, 0x00, sizeof(out)); 377 tt_int_op(64, OP_EQ, 378 secret_to_key_compute_key(out, 64, spec, 16, 379 "pleaseletmein", 13, 2)); 380 test_memeq_hex(out, 381 "7023bdcb3afd7348461c06cd81fd38eb" 382 "fda8fbba904f8e3ea9b543f6545da1f2" 383 "d5432955613f0fcf62d49705242a9af9" 384 "e61e85dc0d651e40dfcf017b45575887"); 385 386 base16_decode((char*)spec, sizeof(spec), 387 "536f6469756d43686c6f72696465" "1430", 32); 388 memset(out, 0x00, sizeof(out)); 389 tt_int_op(64, OP_EQ, 390 secret_to_key_compute_key(out, 64, spec, 16, 391 "pleaseletmein", 13, 2)); 392 test_memeq_hex(out, 393 "2101cb9b6a511aaeaddbbe09cf70f881" 394 "ec568d574a2ffd4dabe5ee9820adaa47" 395 "8e56fd8f4ba5d09ffa1c6d927c40f4c3" 396 "37304049e8a952fbcbf45c6fa77a41a4"); 397 398 done: 399 tor_free(mem_op_hex_tmp); 400 } 401 402 static void 403 test_crypto_pbkdf2_vectors(void *arg) 404 { 405 char *mem_op_hex_tmp = NULL; 406 uint8_t spec[64], out[64]; 407 (void)arg; 408 409 /* Test vectors from RFC6070, section 2 */ 410 base16_decode((char*)spec, sizeof(spec), 411 "73616c74" "00" , 10); 412 memset(out, 0x00, sizeof(out)); 413 tt_int_op(20, OP_EQ, 414 secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1)); 415 test_memeq_hex(out, "0c60c80f961f0e71f3a9b524af6012062fe037a6"); 416 417 base16_decode((char*)spec, sizeof(spec), 418 "73616c74" "01" , 10); 419 memset(out, 0x00, sizeof(out)); 420 tt_int_op(20, OP_EQ, 421 secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1)); 422 test_memeq_hex(out, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"); 423 424 base16_decode((char*)spec, sizeof(spec), 425 "73616c74" "0C" , 10); 426 memset(out, 0x00, sizeof(out)); 427 tt_int_op(20, OP_EQ, 428 secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1)); 429 test_memeq_hex(out, "4b007901b765489abead49d926f721d065a429c1"); 430 431 /* This is the very slow one here. When enabled, it accounts for roughly 432 * half the time spent in test-slow. */ 433 /* 434 base16_decode((char*)spec, sizeof(spec), 435 "73616c74" "18" , 10); 436 memset(out, 0x00, sizeof(out)); 437 tt_int_op(20, OP_EQ, 438 secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1)); 439 test_memeq_hex(out, "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984"); 440 */ 441 442 base16_decode((char*)spec, sizeof(spec), 443 "73616c7453414c5473616c7453414c5473616c745" 444 "3414c5473616c7453414c5473616c74" "0C" , 74); 445 memset(out, 0x00, sizeof(out)); 446 tt_int_op(25, OP_EQ, 447 secret_to_key_compute_key(out, 25, spec, 37, 448 "passwordPASSWORDpassword", 24, 1)); 449 test_memeq_hex(out, "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038"); 450 451 base16_decode((char*)spec, sizeof(spec), 452 "7361006c74" "0c" , 12); 453 memset(out, 0x00, sizeof(out)); 454 tt_int_op(16, OP_EQ, 455 secret_to_key_compute_key(out, 16, spec, 6, "pass\0word", 9, 1)); 456 test_memeq_hex(out, "56fa6aa75548099dcc37d7f03425e0c3"); 457 458 done: 459 tor_free(mem_op_hex_tmp); 460 } 461 462 static void 463 test_crypto_pwbox(void *arg) 464 { 465 uint8_t *boxed=NULL, *decoded=NULL; 466 size_t len, dlen; 467 unsigned i; 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"; 473 474 const unsigned flags[] = { 0, 475 S2K_FLAG_NO_SCRYPT, 476 S2K_FLAG_LOW_MEM, 477 S2K_FLAG_NO_SCRYPT|S2K_FLAG_LOW_MEM, 478 S2K_FLAG_USE_PBKDF2 }; 479 (void)arg; 480 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])); 485 tt_assert(boxed); 486 tt_assert(len > 128+32); 487 488 tt_int_op(0, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len, 489 pw, strlen(pw))); 490 491 tt_assert(decoded); 492 tt_uint_op(dlen, OP_EQ, strlen(msg)); 493 tt_mem_op(decoded, OP_EQ, msg, dlen); 494 495 tor_free(decoded); 496 497 tt_int_op(UNPWBOX_BAD_SECRET, OP_EQ, crypto_unpwbox(&decoded, &dlen, 498 boxed, len, 499 pw, strlen(pw)-1)); 500 boxed[len-1] ^= 1; 501 tt_int_op(UNPWBOX_BAD_SECRET, OP_EQ, crypto_unpwbox(&decoded, &dlen, 502 boxed, len, 503 pw, strlen(pw))); 504 boxed[0] = 255; 505 tt_int_op(UNPWBOX_CORRUPTED, OP_EQ, crypto_unpwbox(&decoded, &dlen, 506 boxed, len, 507 pw, strlen(pw))); 508 509 tor_free(boxed); 510 } 511 512 done: 513 tor_free(boxed); 514 tor_free(decoded); 515 } 516 517 static void 518 test_crypto_ed25519_fuzz_donna(void *arg) 519 { 520 const unsigned iters = 1024; 521 uint8_t msg[1024]; 522 unsigned i; 523 (void)arg; 524 525 tt_uint_op(iters, OP_EQ, sizeof(msg)); 526 crypto_rand((char*) msg, sizeof(msg)); 527 528 /* Fuzz Ed25519-donna vs ref10, alternating the implementation used to 529 * generate keys/sign per iteration. 530 */ 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; 538 int bit = 0; 539 540 crypto_rand((char*) blinding, sizeof(blinding)); 541 542 /* Impl. A: 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. 548 */ 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)); 554 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)); 558 559 /* Impl. B: 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. 565 */ 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); 569 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); 572 573 tt_int_op(0, OP_EQ, ed25519_checksig(&sig, msg, i, &pk)); 574 sig.sig[0] ^= 15; 575 tt_int_op(-1, OP_EQ, ed25519_checksig(&sig, msg, sizeof(msg), &pk)); 576 577 tt_int_op(0, OP_EQ, ed25519_checksig(&sig_blind, msg, i, &pk_blind)); 578 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); 582 } 583 584 done: 585 ; 586 } 587 588 static void 589 test_crypto_equix(void *arg) 590 { 591 (void)arg; 592 593 static const struct { 594 const char *challenge_literal; 595 size_t num_solutions; 596 equix_solution solutions[EQUIX_MAX_SOLS]; 597 } vectors[] = { 598 { "zzz", 1, { 599 {{ 0xae21, 0xd392, 0x3215, 0xdd9c, 0x2f08, 0x93df, 0x232c, 0xe5dc }}, 600 }}, 601 { "rrr", 1, { 602 {{ 0x0873, 0x57a8, 0x73e0, 0x912e, 0x1ca8, 0xad96, 0x9abd, 0xd7de }}, 603 }}, 604 { "qqq", 0, {{{ 0 }}} }, 605 { "0123456789", 0, {{{ 0 }}} }, 606 { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0, {{{ 0 }}} }, 607 { "", 3, { 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 }}, 611 }}, 612 { "a", 3, { 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 }}, 616 }}, 617 { "abc", 2, { 618 {{ 0x371f, 0x8865, 0x8189, 0xfbc3, 0x26df, 0xe4c0, 0xab39, 0xfe5a }}, 619 {{ 0x2101, 0xb88f, 0xc525, 0xccb3, 0x5785, 0xa41e, 0x4fba, 0xed18 }}, 620 }}, 621 { "abce", 4, { 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 }}, 626 }}, 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 }}, 633 }}, 634 }; 635 636 static const struct { 637 equix_ctx_flags flags; 638 equix_result expected; 639 equix_solution_flags sol_flags; 640 } variations[] = { 641 {0, EQUIX_OK, 0}, 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 647 }, 648 { EQUIX_CTX_MUST_COMPILE, EQUIX_FAIL_ORDER, 649 EQUIX_SOLVER_DID_USE_COMPILER 650 }, 651 { EQUIX_CTX_MUST_COMPILE, EQUIX_FAIL_PARTIAL_SUM, 652 EQUIX_SOLVER_DID_USE_COMPILER 653 }, 654 #endif 655 }; 656 657 const unsigned num_vectors = sizeof vectors / sizeof vectors[0]; 658 const unsigned num_variations = sizeof variations / sizeof variations[0]; 659 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); 663 664 const size_t num_sols = vectors[vec_i].num_solutions; 665 const equix_solution *sols_expected = vectors[vec_i].solutions; 666 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; 671 672 equix_solutions_buffer output; 673 equix_ctx *solve_ctx = NULL, *verify_ctx = NULL; 674 675 solve_ctx = equix_alloc(EQUIX_CTX_SOLVE | flags); 676 tt_ptr_op(solve_ctx, OP_NE, NULL); 677 678 /* Solve phase: Make sure the test vector matches */ 679 memset(&output, 0xa5, sizeof output); 680 equix_result result; 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)); 689 690 verify_ctx = equix_alloc(EQUIX_CTX_VERIFY | flags); 691 tt_ptr_op(verify_ctx, OP_NE, NULL); 692 693 /* Use each solution for positive and negative tests of verify */ 694 for (size_t sol_i = 0; sol_i < num_sols; sol_i++) { 695 equix_idx tmp_idx; 696 equix_solution *sol = &output.sols[sol_i]; 697 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 */ 705 sol->idx[0]++; 706 } 707 708 result = equix_verify(verify_ctx, challenge_literal, 709 challenge_len, sol); 710 tt_int_op(expected, OP_EQ, result); 711 } 712 713 equix_free(verify_ctx); 714 } 715 } 716 717 done: 718 ; 719 } 720 721 #ifndef COCCI 722 #define CRYPTO_LEGACY(name) \ 723 { #name, test_crypto_ ## name , 0, NULL, NULL } 724 725 #define ED25519_TEST_ONE(name, fl, which) \ 726 { #name "/ed25519_" which, test_crypto_ed25519_ ## name, (fl), \ 727 &ed25519_test_setup, (void*)which } 728 729 #define ED25519_TEST(name, fl) \ 730 ED25519_TEST_ONE(name, (fl), "donna"), \ 731 ED25519_TEST_ONE(name, (fl), "ref10") 732 #endif /* !defined(COCCI) */ 733 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, 738 (void*)"scrypt" }, 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 }, 743 #endif 744 #endif /* defined(HAVE_LIBSCRYPT) */ 745 { "s2k_pbkdf2", test_crypto_s2k_general, 0, &passthrough_setup, 746 (void*)"pbkdf2" }, 747 { "s2k_rfc2440_general", test_crypto_s2k_general, 0, &passthrough_setup, 748 (void*)"rfc2440" }, 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 }, 757 END_OF_TESTCASES 758 };