Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 
 
 

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