Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

633 строки
19 KiB

  1. /* Copyright (c) 2014, Google Inc.
  2. *
  3. * Permission to use, copy, modify, and/or distribute this software for any
  4. * purpose with or without fee is hereby granted, provided that the above
  5. * copyright notice and this permission notice appear in all copies.
  6. *
  7. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  10. * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  12. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  13. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
  14. #include <string>
  15. #include <functional>
  16. #include <memory>
  17. #include <vector>
  18. #include <stdint.h>
  19. #include <string.h>
  20. #include <openssl/aead.h>
  21. #include <openssl/curve25519.h>
  22. #include <openssl/digest.h>
  23. #include <openssl/err.h>
  24. #include <openssl/newhope.h>
  25. #include <openssl/nid.h>
  26. #include <openssl/rand.h>
  27. #include <openssl/rsa.h>
  28. #if defined(OPENSSL_WINDOWS)
  29. OPENSSL_MSVC_PRAGMA(warning(push, 3))
  30. #include <windows.h>
  31. OPENSSL_MSVC_PRAGMA(warning(pop))
  32. #elif defined(OPENSSL_APPLE)
  33. #include <sys/time.h>
  34. #endif
  35. #include "../crypto/test/scoped_types.h"
  36. #include "internal.h"
  37. // TimeResults represents the results of benchmarking a function.
  38. struct TimeResults {
  39. // num_calls is the number of function calls done in the time period.
  40. unsigned num_calls;
  41. // us is the number of microseconds that elapsed in the time period.
  42. unsigned us;
  43. void Print(const std::string &description) {
  44. printf("Did %u %s operations in %uus (%.1f ops/sec)\n", num_calls,
  45. description.c_str(), us,
  46. (static_cast<double>(num_calls) / us) * 1000000);
  47. }
  48. void PrintWithBytes(const std::string &description, size_t bytes_per_call) {
  49. printf("Did %u %s operations in %uus (%.1f ops/sec): %.1f MB/s\n",
  50. num_calls, description.c_str(), us,
  51. (static_cast<double>(num_calls) / us) * 1000000,
  52. static_cast<double>(bytes_per_call * num_calls) / us);
  53. }
  54. };
  55. #if defined(OPENSSL_WINDOWS)
  56. static uint64_t time_now() { return GetTickCount64() * 1000; }
  57. #elif defined(OPENSSL_APPLE)
  58. static uint64_t time_now() {
  59. struct timeval tv;
  60. uint64_t ret;
  61. gettimeofday(&tv, NULL);
  62. ret = tv.tv_sec;
  63. ret *= 1000000;
  64. ret += tv.tv_usec;
  65. return ret;
  66. }
  67. #else
  68. static uint64_t time_now() {
  69. struct timespec ts;
  70. clock_gettime(CLOCK_MONOTONIC, &ts);
  71. uint64_t ret = ts.tv_sec;
  72. ret *= 1000000;
  73. ret += ts.tv_nsec / 1000;
  74. return ret;
  75. }
  76. #endif
  77. static bool TimeFunction(TimeResults *results, std::function<bool()> func) {
  78. // kTotalMS is the total amount of time that we'll aim to measure a function
  79. // for.
  80. static const uint64_t kTotalUS = 1000000;
  81. uint64_t start = time_now(), now, delta;
  82. unsigned done = 0, iterations_between_time_checks;
  83. if (!func()) {
  84. return false;
  85. }
  86. now = time_now();
  87. delta = now - start;
  88. if (delta == 0) {
  89. iterations_between_time_checks = 250;
  90. } else {
  91. // Aim for about 100ms between time checks.
  92. iterations_between_time_checks =
  93. static_cast<double>(100000) / static_cast<double>(delta);
  94. if (iterations_between_time_checks > 1000) {
  95. iterations_between_time_checks = 1000;
  96. } else if (iterations_between_time_checks < 1) {
  97. iterations_between_time_checks = 1;
  98. }
  99. }
  100. for (;;) {
  101. for (unsigned i = 0; i < iterations_between_time_checks; i++) {
  102. if (!func()) {
  103. return false;
  104. }
  105. done++;
  106. }
  107. now = time_now();
  108. if (now - start > kTotalUS) {
  109. break;
  110. }
  111. }
  112. results->us = now - start;
  113. results->num_calls = done;
  114. return true;
  115. }
  116. static bool SpeedRSA(const std::string &key_name, RSA *key,
  117. const std::string &selected) {
  118. if (!selected.empty() && key_name.find(selected) == std::string::npos) {
  119. return true;
  120. }
  121. std::unique_ptr<uint8_t[]> sig(new uint8_t[RSA_size(key)]);
  122. const uint8_t fake_sha256_hash[32] = {0};
  123. unsigned sig_len;
  124. TimeResults results;
  125. if (!TimeFunction(&results,
  126. [key, &sig, &fake_sha256_hash, &sig_len]() -> bool {
  127. return RSA_sign(NID_sha256, fake_sha256_hash, sizeof(fake_sha256_hash),
  128. sig.get(), &sig_len, key);
  129. })) {
  130. fprintf(stderr, "RSA_sign failed.\n");
  131. ERR_print_errors_fp(stderr);
  132. return false;
  133. }
  134. results.Print(key_name + " signing");
  135. if (!TimeFunction(&results,
  136. [key, &fake_sha256_hash, &sig, sig_len]() -> bool {
  137. return RSA_verify(NID_sha256, fake_sha256_hash,
  138. sizeof(fake_sha256_hash), sig.get(), sig_len, key);
  139. })) {
  140. fprintf(stderr, "RSA_verify failed.\n");
  141. ERR_print_errors_fp(stderr);
  142. return false;
  143. }
  144. results.Print(key_name + " verify");
  145. return true;
  146. }
  147. static uint8_t *align(uint8_t *in, unsigned alignment) {
  148. return reinterpret_cast<uint8_t *>(
  149. (reinterpret_cast<uintptr_t>(in) + alignment) &
  150. ~static_cast<size_t>(alignment - 1));
  151. }
  152. static bool SpeedAEADChunk(const EVP_AEAD *aead, const std::string &name,
  153. size_t chunk_len, size_t ad_len) {
  154. static const unsigned kAlignment = 16;
  155. EVP_AEAD_CTX ctx;
  156. const size_t key_len = EVP_AEAD_key_length(aead);
  157. const size_t nonce_len = EVP_AEAD_nonce_length(aead);
  158. const size_t overhead_len = EVP_AEAD_max_overhead(aead);
  159. std::unique_ptr<uint8_t[]> key(new uint8_t[key_len]);
  160. memset(key.get(), 0, key_len);
  161. std::unique_ptr<uint8_t[]> nonce(new uint8_t[nonce_len]);
  162. memset(nonce.get(), 0, nonce_len);
  163. std::unique_ptr<uint8_t[]> in_storage(new uint8_t[chunk_len + kAlignment]);
  164. std::unique_ptr<uint8_t[]> out_storage(new uint8_t[chunk_len + overhead_len + kAlignment]);
  165. std::unique_ptr<uint8_t[]> ad(new uint8_t[ad_len]);
  166. memset(ad.get(), 0, ad_len);
  167. uint8_t *const in = align(in_storage.get(), kAlignment);
  168. memset(in, 0, chunk_len);
  169. uint8_t *const out = align(out_storage.get(), kAlignment);
  170. memset(out, 0, chunk_len + overhead_len);
  171. if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, key.get(), key_len,
  172. EVP_AEAD_DEFAULT_TAG_LENGTH,
  173. evp_aead_seal)) {
  174. fprintf(stderr, "Failed to create EVP_AEAD_CTX.\n");
  175. ERR_print_errors_fp(stderr);
  176. return false;
  177. }
  178. TimeResults results;
  179. if (!TimeFunction(&results, [chunk_len, overhead_len, nonce_len, ad_len, in,
  180. out, &ctx, &nonce, &ad]() -> bool {
  181. size_t out_len;
  182. return EVP_AEAD_CTX_seal(
  183. &ctx, out, &out_len, chunk_len + overhead_len, nonce.get(),
  184. nonce_len, in, chunk_len, ad.get(), ad_len);
  185. })) {
  186. fprintf(stderr, "EVP_AEAD_CTX_seal failed.\n");
  187. ERR_print_errors_fp(stderr);
  188. return false;
  189. }
  190. results.PrintWithBytes(name + " seal", chunk_len);
  191. EVP_AEAD_CTX_cleanup(&ctx);
  192. return true;
  193. }
  194. static bool SpeedAEAD(const EVP_AEAD *aead, const std::string &name,
  195. size_t ad_len, const std::string &selected) {
  196. if (!selected.empty() && name.find(selected) == std::string::npos) {
  197. return true;
  198. }
  199. return SpeedAEADChunk(aead, name + " (16 bytes)", 16, ad_len) &&
  200. SpeedAEADChunk(aead, name + " (1350 bytes)", 1350, ad_len) &&
  201. SpeedAEADChunk(aead, name + " (8192 bytes)", 8192, ad_len);
  202. }
  203. static bool SpeedHashChunk(const EVP_MD *md, const std::string &name,
  204. size_t chunk_len) {
  205. EVP_MD_CTX *ctx = EVP_MD_CTX_create();
  206. uint8_t scratch[8192];
  207. if (chunk_len > sizeof(scratch)) {
  208. return false;
  209. }
  210. TimeResults results;
  211. if (!TimeFunction(&results, [ctx, md, chunk_len, &scratch]() -> bool {
  212. uint8_t digest[EVP_MAX_MD_SIZE];
  213. unsigned int md_len;
  214. return EVP_DigestInit_ex(ctx, md, NULL /* ENGINE */) &&
  215. EVP_DigestUpdate(ctx, scratch, chunk_len) &&
  216. EVP_DigestFinal_ex(ctx, digest, &md_len);
  217. })) {
  218. fprintf(stderr, "EVP_DigestInit_ex failed.\n");
  219. ERR_print_errors_fp(stderr);
  220. return false;
  221. }
  222. results.PrintWithBytes(name, chunk_len);
  223. EVP_MD_CTX_destroy(ctx);
  224. return true;
  225. }
  226. static bool SpeedHash(const EVP_MD *md, const std::string &name,
  227. const std::string &selected) {
  228. if (!selected.empty() && name.find(selected) == std::string::npos) {
  229. return true;
  230. }
  231. return SpeedHashChunk(md, name + " (16 bytes)", 16) &&
  232. SpeedHashChunk(md, name + " (256 bytes)", 256) &&
  233. SpeedHashChunk(md, name + " (8192 bytes)", 8192);
  234. }
  235. static bool SpeedRandomChunk(const std::string name, size_t chunk_len) {
  236. uint8_t scratch[8192];
  237. if (chunk_len > sizeof(scratch)) {
  238. return false;
  239. }
  240. TimeResults results;
  241. if (!TimeFunction(&results, [chunk_len, &scratch]() -> bool {
  242. RAND_bytes(scratch, chunk_len);
  243. return true;
  244. })) {
  245. return false;
  246. }
  247. results.PrintWithBytes(name, chunk_len);
  248. return true;
  249. }
  250. static bool SpeedRandom(const std::string &selected) {
  251. if (!selected.empty() && selected != "RNG") {
  252. return true;
  253. }
  254. return SpeedRandomChunk("RNG (16 bytes)", 16) &&
  255. SpeedRandomChunk("RNG (256 bytes)", 256) &&
  256. SpeedRandomChunk("RNG (8192 bytes)", 8192);
  257. }
  258. static bool SpeedECDHCurve(const std::string &name, int nid,
  259. const std::string &selected) {
  260. if (!selected.empty() && name.find(selected) == std::string::npos) {
  261. return true;
  262. }
  263. TimeResults results;
  264. if (!TimeFunction(&results, [nid]() -> bool {
  265. ScopedEC_KEY key(EC_KEY_new_by_curve_name(nid));
  266. if (!key ||
  267. !EC_KEY_generate_key(key.get())) {
  268. return false;
  269. }
  270. const EC_GROUP *const group = EC_KEY_get0_group(key.get());
  271. ScopedEC_POINT point(EC_POINT_new(group));
  272. ScopedBN_CTX ctx(BN_CTX_new());
  273. ScopedBIGNUM x(BN_new());
  274. ScopedBIGNUM y(BN_new());
  275. if (!point || !ctx || !x || !y ||
  276. !EC_POINT_mul(group, point.get(), NULL,
  277. EC_KEY_get0_public_key(key.get()),
  278. EC_KEY_get0_private_key(key.get()), ctx.get()) ||
  279. !EC_POINT_get_affine_coordinates_GFp(group, point.get(), x.get(),
  280. y.get(), ctx.get())) {
  281. return false;
  282. }
  283. return true;
  284. })) {
  285. return false;
  286. }
  287. results.Print(name);
  288. return true;
  289. }
  290. static bool SpeedECDSACurve(const std::string &name, int nid,
  291. const std::string &selected) {
  292. if (!selected.empty() && name.find(selected) == std::string::npos) {
  293. return true;
  294. }
  295. ScopedEC_KEY key(EC_KEY_new_by_curve_name(nid));
  296. if (!key ||
  297. !EC_KEY_generate_key(key.get())) {
  298. return false;
  299. }
  300. uint8_t signature[256];
  301. if (ECDSA_size(key.get()) > sizeof(signature)) {
  302. return false;
  303. }
  304. uint8_t digest[20];
  305. memset(digest, 42, sizeof(digest));
  306. unsigned sig_len;
  307. TimeResults results;
  308. if (!TimeFunction(&results, [&key, &signature, &digest, &sig_len]() -> bool {
  309. return ECDSA_sign(0, digest, sizeof(digest), signature, &sig_len,
  310. key.get()) == 1;
  311. })) {
  312. return false;
  313. }
  314. results.Print(name + " signing");
  315. if (!TimeFunction(&results, [&key, &signature, &digest, sig_len]() -> bool {
  316. return ECDSA_verify(0, digest, sizeof(digest), signature, sig_len,
  317. key.get()) == 1;
  318. })) {
  319. return false;
  320. }
  321. results.Print(name + " verify");
  322. return true;
  323. }
  324. static bool SpeedECDH(const std::string &selected) {
  325. return SpeedECDHCurve("ECDH P-224", NID_secp224r1, selected) &&
  326. SpeedECDHCurve("ECDH P-256", NID_X9_62_prime256v1, selected) &&
  327. SpeedECDHCurve("ECDH P-384", NID_secp384r1, selected) &&
  328. SpeedECDHCurve("ECDH P-521", NID_secp521r1, selected);
  329. }
  330. static bool SpeedECDSA(const std::string &selected) {
  331. return SpeedECDSACurve("ECDSA P-224", NID_secp224r1, selected) &&
  332. SpeedECDSACurve("ECDSA P-256", NID_X9_62_prime256v1, selected) &&
  333. SpeedECDSACurve("ECDSA P-384", NID_secp384r1, selected) &&
  334. SpeedECDSACurve("ECDSA P-521", NID_secp521r1, selected);
  335. }
  336. static bool Speed25519(const std::string &selected) {
  337. if (!selected.empty() && selected.find("25519") == std::string::npos) {
  338. return true;
  339. }
  340. TimeResults results;
  341. uint8_t public_key[32], private_key[64];
  342. if (!TimeFunction(&results, [&public_key, &private_key]() -> bool {
  343. ED25519_keypair(public_key, private_key);
  344. return true;
  345. })) {
  346. return false;
  347. }
  348. results.Print("Ed25519 key generation");
  349. static const uint8_t kMessage[] = {0, 1, 2, 3, 4, 5};
  350. uint8_t signature[64];
  351. if (!TimeFunction(&results, [&private_key, &signature]() -> bool {
  352. return ED25519_sign(signature, kMessage, sizeof(kMessage),
  353. private_key) == 1;
  354. })) {
  355. return false;
  356. }
  357. results.Print("Ed25519 signing");
  358. if (!TimeFunction(&results, [&public_key, &signature]() -> bool {
  359. return ED25519_verify(kMessage, sizeof(kMessage), signature,
  360. public_key) == 1;
  361. })) {
  362. fprintf(stderr, "Ed25519 verify failed.\n");
  363. return false;
  364. }
  365. results.Print("Ed25519 verify");
  366. if (!TimeFunction(&results, []() -> bool {
  367. uint8_t out[32], in[32];
  368. memset(in, 0, sizeof(in));
  369. X25519_public_from_private(out, in);
  370. return true;
  371. })) {
  372. fprintf(stderr, "Curve25519 base-point multiplication failed.\n");
  373. return false;
  374. }
  375. results.Print("Curve25519 base-point multiplication");
  376. if (!TimeFunction(&results, []() -> bool {
  377. uint8_t out[32], in1[32], in2[32];
  378. memset(in1, 0, sizeof(in1));
  379. memset(in2, 0, sizeof(in2));
  380. in1[0] = 1;
  381. in2[0] = 9;
  382. return X25519(out, in1, in2) == 1;
  383. })) {
  384. fprintf(stderr, "Curve25519 arbitrary point multiplication failed.\n");
  385. return false;
  386. }
  387. results.Print("Curve25519 arbitrary point multiplication");
  388. return true;
  389. }
  390. static bool SpeedSPAKE2(const std::string &selected) {
  391. if (!selected.empty() && selected.find("SPAKE2") == std::string::npos) {
  392. return true;
  393. }
  394. TimeResults results;
  395. static const uint8_t kAliceName[] = {'A'};
  396. static const uint8_t kBobName[] = {'B'};
  397. static const uint8_t kPassword[] = "password";
  398. ScopedSPAKE2_CTX alice(SPAKE2_CTX_new(spake2_role_alice, kAliceName,
  399. sizeof(kAliceName), kBobName,
  400. sizeof(kBobName)));
  401. uint8_t alice_msg[SPAKE2_MAX_MSG_SIZE];
  402. size_t alice_msg_len;
  403. if (!SPAKE2_generate_msg(alice.get(), alice_msg, &alice_msg_len,
  404. sizeof(alice_msg),
  405. kPassword, sizeof(kPassword))) {
  406. fprintf(stderr, "SPAKE2_generate_msg failed.\n");
  407. return false;
  408. }
  409. if (!TimeFunction(&results, [&alice_msg, alice_msg_len]() -> bool {
  410. ScopedSPAKE2_CTX bob(SPAKE2_CTX_new(spake2_role_bob, kBobName,
  411. sizeof(kBobName), kAliceName,
  412. sizeof(kAliceName)));
  413. uint8_t bob_msg[SPAKE2_MAX_MSG_SIZE], bob_key[64];
  414. size_t bob_msg_len, bob_key_len;
  415. if (!SPAKE2_generate_msg(bob.get(), bob_msg, &bob_msg_len,
  416. sizeof(bob_msg), kPassword,
  417. sizeof(kPassword)) ||
  418. !SPAKE2_process_msg(bob.get(), bob_key, &bob_key_len,
  419. sizeof(bob_key), alice_msg, alice_msg_len)) {
  420. return false;
  421. }
  422. return true;
  423. })) {
  424. fprintf(stderr, "SPAKE2 failed.\n");
  425. }
  426. results.Print("SPAKE2 over Ed25519");
  427. return true;
  428. }
  429. static bool SpeedNewHope(const std::string &selected) {
  430. if (!selected.empty() && selected.find("newhope") == std::string::npos) {
  431. return true;
  432. }
  433. TimeResults results;
  434. NEWHOPE_POLY *sk = NEWHOPE_POLY_new();
  435. uint8_t acceptmsg[NEWHOPE_ACCEPTMSG_LENGTH];
  436. RAND_bytes(acceptmsg, sizeof(acceptmsg));
  437. if (!TimeFunction(&results, [sk, &acceptmsg]() -> bool {
  438. uint8_t key[SHA256_DIGEST_LENGTH];
  439. uint8_t offermsg[NEWHOPE_OFFERMSG_LENGTH];
  440. NEWHOPE_offer(offermsg, sk);
  441. if (!NEWHOPE_finish(key, sk, acceptmsg, NEWHOPE_ACCEPTMSG_LENGTH)) {
  442. return false;
  443. }
  444. return true;
  445. })) {
  446. fprintf(stderr, "failed to exchange key.\n");
  447. return false;
  448. }
  449. NEWHOPE_POLY_free(sk);
  450. results.Print("newhope key exchange");
  451. return true;
  452. }
  453. bool Speed(const std::vector<std::string> &args) {
  454. std::string selected;
  455. if (args.size() > 1) {
  456. fprintf(stderr, "Usage: bssl speed [speed test selector, i.e. 'RNG']\n");
  457. return false;
  458. }
  459. if (args.size() > 0) {
  460. selected = args[0];
  461. }
  462. RSA *key = RSA_private_key_from_bytes(kDERRSAPrivate2048,
  463. kDERRSAPrivate2048Len);
  464. if (key == NULL) {
  465. fprintf(stderr, "Failed to parse RSA key.\n");
  466. ERR_print_errors_fp(stderr);
  467. return false;
  468. }
  469. if (!SpeedRSA("RSA 2048", key, selected)) {
  470. return false;
  471. }
  472. RSA_free(key);
  473. key = RSA_private_key_from_bytes(kDERRSAPrivate3Prime2048,
  474. kDERRSAPrivate3Prime2048Len);
  475. if (key == NULL) {
  476. fprintf(stderr, "Failed to parse RSA key.\n");
  477. ERR_print_errors_fp(stderr);
  478. return false;
  479. }
  480. if (!SpeedRSA("RSA 2048 (3 prime, e=3)", key, selected)) {
  481. return false;
  482. }
  483. RSA_free(key);
  484. key = RSA_private_key_from_bytes(kDERRSAPrivate4096,
  485. kDERRSAPrivate4096Len);
  486. if (key == NULL) {
  487. fprintf(stderr, "Failed to parse 4096-bit RSA key.\n");
  488. ERR_print_errors_fp(stderr);
  489. return 1;
  490. }
  491. if (!SpeedRSA("RSA 4096", key, selected)) {
  492. return false;
  493. }
  494. RSA_free(key);
  495. // kTLSADLen is the number of bytes of additional data that TLS passes to
  496. // AEADs.
  497. static const size_t kTLSADLen = 13;
  498. // kLegacyADLen is the number of bytes that TLS passes to the "legacy" AEADs.
  499. // These are AEADs that weren't originally defined as AEADs, but which we use
  500. // via the AEAD interface. In order for that to work, they have some TLS
  501. // knowledge in them and construct a couple of the AD bytes internally.
  502. static const size_t kLegacyADLen = kTLSADLen - 2;
  503. if (!SpeedAEAD(EVP_aead_aes_128_gcm(), "AES-128-GCM", kTLSADLen, selected) ||
  504. !SpeedAEAD(EVP_aead_aes_256_gcm(), "AES-256-GCM", kTLSADLen, selected) ||
  505. !SpeedAEAD(EVP_aead_chacha20_poly1305(), "ChaCha20-Poly1305", kTLSADLen,
  506. selected) ||
  507. !SpeedAEAD(EVP_aead_chacha20_poly1305_old(), "ChaCha20-Poly1305-Old",
  508. kTLSADLen, selected) ||
  509. !SpeedAEAD(EVP_aead_rc4_md5_tls(), "RC4-MD5", kLegacyADLen, selected) ||
  510. !SpeedAEAD(EVP_aead_rc4_sha1_tls(), "RC4-SHA1", kLegacyADLen, selected) ||
  511. !SpeedAEAD(EVP_aead_des_ede3_cbc_sha1_tls(), "DES-EDE3-CBC-SHA1",
  512. kLegacyADLen, selected) ||
  513. !SpeedAEAD(EVP_aead_aes_128_cbc_sha1_tls(), "AES-128-CBC-SHA1",
  514. kLegacyADLen, selected) ||
  515. !SpeedAEAD(EVP_aead_aes_256_cbc_sha1_tls(), "AES-256-CBC-SHA1",
  516. kLegacyADLen, selected) ||
  517. !SpeedHash(EVP_sha1(), "SHA-1", selected) ||
  518. !SpeedHash(EVP_sha256(), "SHA-256", selected) ||
  519. !SpeedHash(EVP_sha512(), "SHA-512", selected) ||
  520. !SpeedRandom(selected) ||
  521. !SpeedECDH(selected) ||
  522. !SpeedECDSA(selected) ||
  523. !Speed25519(selected) ||
  524. !SpeedSPAKE2(selected) ||
  525. !SpeedNewHope(selected)) {
  526. return false;
  527. }
  528. return true;
  529. }