You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

671 lines
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. bssl::ScopedEVP_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.get(), 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(ctx.get(), out, &out_len,
  208. 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. return true;
  217. }
  218. static bool SpeedAEAD(const EVP_AEAD *aead, const std::string &name,
  219. size_t ad_len, const std::string &selected) {
  220. if (!selected.empty() && name.find(selected) == std::string::npos) {
  221. return true;
  222. }
  223. return SpeedAEADChunk(aead, name + " (16 bytes)", 16, ad_len) &&
  224. SpeedAEADChunk(aead, name + " (1350 bytes)", 1350, ad_len) &&
  225. SpeedAEADChunk(aead, name + " (8192 bytes)", 8192, ad_len);
  226. }
  227. static bool SpeedHashChunk(const EVP_MD *md, const std::string &name,
  228. size_t chunk_len) {
  229. EVP_MD_CTX *ctx = EVP_MD_CTX_create();
  230. uint8_t scratch[8192];
  231. if (chunk_len > sizeof(scratch)) {
  232. return false;
  233. }
  234. TimeResults results;
  235. if (!TimeFunction(&results, [ctx, md, chunk_len, &scratch]() -> bool {
  236. uint8_t digest[EVP_MAX_MD_SIZE];
  237. unsigned int md_len;
  238. return EVP_DigestInit_ex(ctx, md, NULL /* ENGINE */) &&
  239. EVP_DigestUpdate(ctx, scratch, chunk_len) &&
  240. EVP_DigestFinal_ex(ctx, digest, &md_len);
  241. })) {
  242. fprintf(stderr, "EVP_DigestInit_ex failed.\n");
  243. ERR_print_errors_fp(stderr);
  244. return false;
  245. }
  246. results.PrintWithBytes(name, chunk_len);
  247. EVP_MD_CTX_destroy(ctx);
  248. return true;
  249. }
  250. static bool SpeedHash(const EVP_MD *md, const std::string &name,
  251. const std::string &selected) {
  252. if (!selected.empty() && name.find(selected) == std::string::npos) {
  253. return true;
  254. }
  255. return SpeedHashChunk(md, name + " (16 bytes)", 16) &&
  256. SpeedHashChunk(md, name + " (256 bytes)", 256) &&
  257. SpeedHashChunk(md, name + " (8192 bytes)", 8192);
  258. }
  259. static bool SpeedRandomChunk(const std::string &name, size_t chunk_len) {
  260. uint8_t scratch[8192];
  261. if (chunk_len > sizeof(scratch)) {
  262. return false;
  263. }
  264. TimeResults results;
  265. if (!TimeFunction(&results, [chunk_len, &scratch]() -> bool {
  266. RAND_bytes(scratch, chunk_len);
  267. return true;
  268. })) {
  269. return false;
  270. }
  271. results.PrintWithBytes(name, chunk_len);
  272. return true;
  273. }
  274. static bool SpeedRandom(const std::string &selected) {
  275. if (!selected.empty() && selected != "RNG") {
  276. return true;
  277. }
  278. return SpeedRandomChunk("RNG (16 bytes)", 16) &&
  279. SpeedRandomChunk("RNG (256 bytes)", 256) &&
  280. SpeedRandomChunk("RNG (8192 bytes)", 8192);
  281. }
  282. static bool SpeedECDHCurve(const std::string &name, int nid,
  283. const std::string &selected) {
  284. if (!selected.empty() && name.find(selected) == std::string::npos) {
  285. return true;
  286. }
  287. TimeResults results;
  288. if (!TimeFunction(&results, [nid]() -> bool {
  289. bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(nid));
  290. if (!key ||
  291. !EC_KEY_generate_key(key.get())) {
  292. return false;
  293. }
  294. const EC_GROUP *const group = EC_KEY_get0_group(key.get());
  295. bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group));
  296. bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
  297. bssl::UniquePtr<BIGNUM> x(BN_new());
  298. bssl::UniquePtr<BIGNUM> y(BN_new());
  299. if (!point || !ctx || !x || !y ||
  300. !EC_POINT_mul(group, point.get(), NULL,
  301. EC_KEY_get0_public_key(key.get()),
  302. EC_KEY_get0_private_key(key.get()), ctx.get()) ||
  303. !EC_POINT_get_affine_coordinates_GFp(group, point.get(), x.get(),
  304. y.get(), ctx.get())) {
  305. return false;
  306. }
  307. return true;
  308. })) {
  309. return false;
  310. }
  311. results.Print(name);
  312. return true;
  313. }
  314. static bool SpeedECDSACurve(const std::string &name, int nid,
  315. const std::string &selected) {
  316. if (!selected.empty() && name.find(selected) == std::string::npos) {
  317. return true;
  318. }
  319. bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(nid));
  320. if (!key ||
  321. !EC_KEY_generate_key(key.get())) {
  322. return false;
  323. }
  324. uint8_t signature[256];
  325. if (ECDSA_size(key.get()) > sizeof(signature)) {
  326. return false;
  327. }
  328. uint8_t digest[20];
  329. memset(digest, 42, sizeof(digest));
  330. unsigned sig_len;
  331. TimeResults results;
  332. if (!TimeFunction(&results, [&key, &signature, &digest, &sig_len]() -> bool {
  333. return ECDSA_sign(0, digest, sizeof(digest), signature, &sig_len,
  334. key.get()) == 1;
  335. })) {
  336. return false;
  337. }
  338. results.Print(name + " signing");
  339. if (!TimeFunction(&results, [&key, &signature, &digest, sig_len]() -> bool {
  340. return ECDSA_verify(0, digest, sizeof(digest), signature, sig_len,
  341. key.get()) == 1;
  342. })) {
  343. return false;
  344. }
  345. results.Print(name + " verify");
  346. return true;
  347. }
  348. static bool SpeedECDH(const std::string &selected) {
  349. return SpeedECDHCurve("ECDH P-224", NID_secp224r1, selected) &&
  350. SpeedECDHCurve("ECDH P-256", NID_X9_62_prime256v1, selected) &&
  351. SpeedECDHCurve("ECDH P-384", NID_secp384r1, selected) &&
  352. SpeedECDHCurve("ECDH P-521", NID_secp521r1, selected);
  353. }
  354. static bool SpeedECDSA(const std::string &selected) {
  355. return SpeedECDSACurve("ECDSA P-224", NID_secp224r1, selected) &&
  356. SpeedECDSACurve("ECDSA P-256", NID_X9_62_prime256v1, selected) &&
  357. SpeedECDSACurve("ECDSA P-384", NID_secp384r1, selected) &&
  358. SpeedECDSACurve("ECDSA P-521", NID_secp521r1, selected);
  359. }
  360. static bool Speed25519(const std::string &selected) {
  361. if (!selected.empty() && selected.find("25519") == std::string::npos) {
  362. return true;
  363. }
  364. TimeResults results;
  365. uint8_t public_key[32], private_key[64];
  366. if (!TimeFunction(&results, [&public_key, &private_key]() -> bool {
  367. ED25519_keypair(public_key, private_key);
  368. return true;
  369. })) {
  370. return false;
  371. }
  372. results.Print("Ed25519 key generation");
  373. static const uint8_t kMessage[] = {0, 1, 2, 3, 4, 5};
  374. uint8_t signature[64];
  375. if (!TimeFunction(&results, [&private_key, &signature]() -> bool {
  376. return ED25519_sign(signature, kMessage, sizeof(kMessage),
  377. private_key) == 1;
  378. })) {
  379. return false;
  380. }
  381. results.Print("Ed25519 signing");
  382. if (!TimeFunction(&results, [&public_key, &signature]() -> bool {
  383. return ED25519_verify(kMessage, sizeof(kMessage), signature,
  384. public_key) == 1;
  385. })) {
  386. fprintf(stderr, "Ed25519 verify failed.\n");
  387. return false;
  388. }
  389. results.Print("Ed25519 verify");
  390. if (!TimeFunction(&results, []() -> bool {
  391. uint8_t out[32], in[32];
  392. memset(in, 0, sizeof(in));
  393. X25519_public_from_private(out, in);
  394. return true;
  395. })) {
  396. fprintf(stderr, "Curve25519 base-point multiplication failed.\n");
  397. return false;
  398. }
  399. results.Print("Curve25519 base-point multiplication");
  400. if (!TimeFunction(&results, []() -> bool {
  401. uint8_t out[32], in1[32], in2[32];
  402. memset(in1, 0, sizeof(in1));
  403. memset(in2, 0, sizeof(in2));
  404. in1[0] = 1;
  405. in2[0] = 9;
  406. return X25519(out, in1, in2) == 1;
  407. })) {
  408. fprintf(stderr, "Curve25519 arbitrary point multiplication failed.\n");
  409. return false;
  410. }
  411. results.Print("Curve25519 arbitrary point multiplication");
  412. return true;
  413. }
  414. static bool SpeedSPAKE2(const std::string &selected) {
  415. if (!selected.empty() && selected.find("SPAKE2") == std::string::npos) {
  416. return true;
  417. }
  418. TimeResults results;
  419. static const uint8_t kAliceName[] = {'A'};
  420. static const uint8_t kBobName[] = {'B'};
  421. static const uint8_t kPassword[] = "password";
  422. bssl::UniquePtr<SPAKE2_CTX> alice(SPAKE2_CTX_new(spake2_role_alice,
  423. kAliceName, sizeof(kAliceName), kBobName,
  424. sizeof(kBobName)));
  425. uint8_t alice_msg[SPAKE2_MAX_MSG_SIZE];
  426. size_t alice_msg_len;
  427. if (!SPAKE2_generate_msg(alice.get(), alice_msg, &alice_msg_len,
  428. sizeof(alice_msg),
  429. kPassword, sizeof(kPassword))) {
  430. fprintf(stderr, "SPAKE2_generate_msg failed.\n");
  431. return false;
  432. }
  433. if (!TimeFunction(&results, [&alice_msg, alice_msg_len]() -> bool {
  434. bssl::UniquePtr<SPAKE2_CTX> bob(SPAKE2_CTX_new(spake2_role_bob,
  435. kBobName, sizeof(kBobName), kAliceName,
  436. sizeof(kAliceName)));
  437. uint8_t bob_msg[SPAKE2_MAX_MSG_SIZE], bob_key[64];
  438. size_t bob_msg_len, bob_key_len;
  439. if (!SPAKE2_generate_msg(bob.get(), bob_msg, &bob_msg_len,
  440. sizeof(bob_msg), kPassword,
  441. sizeof(kPassword)) ||
  442. !SPAKE2_process_msg(bob.get(), bob_key, &bob_key_len,
  443. sizeof(bob_key), alice_msg, alice_msg_len)) {
  444. return false;
  445. }
  446. return true;
  447. })) {
  448. fprintf(stderr, "SPAKE2 failed.\n");
  449. }
  450. results.Print("SPAKE2 over Ed25519");
  451. return true;
  452. }
  453. static bool SpeedNewHope(const std::string &selected) {
  454. if (!selected.empty() && selected.find("newhope") == std::string::npos) {
  455. return true;
  456. }
  457. TimeResults results;
  458. bssl::UniquePtr<NEWHOPE_POLY> sk(NEWHOPE_POLY_new());
  459. uint8_t acceptmsg[NEWHOPE_ACCEPTMSG_LENGTH];
  460. RAND_bytes(acceptmsg, sizeof(acceptmsg));
  461. if (!TimeFunction(&results, [&sk, &acceptmsg]() -> bool {
  462. uint8_t key[SHA256_DIGEST_LENGTH];
  463. uint8_t offermsg[NEWHOPE_OFFERMSG_LENGTH];
  464. NEWHOPE_offer(offermsg, sk.get());
  465. if (!NEWHOPE_finish(key, sk.get(), acceptmsg,
  466. NEWHOPE_ACCEPTMSG_LENGTH)) {
  467. return false;
  468. }
  469. return true;
  470. })) {
  471. fprintf(stderr, "failed to exchange key.\n");
  472. return false;
  473. }
  474. results.Print("newhope key exchange");
  475. return true;
  476. }
  477. static const struct argument kArguments[] = {
  478. {
  479. "-filter", kOptionalArgument,
  480. "A filter on the speed tests to run",
  481. },
  482. {
  483. "-timeout", kOptionalArgument,
  484. "The number of seconds to run each test for (default is 1)",
  485. },
  486. {
  487. "", kOptionalArgument, "",
  488. },
  489. };
  490. bool Speed(const std::vector<std::string> &args) {
  491. std::map<std::string, std::string> args_map;
  492. if (!ParseKeyValueArguments(&args_map, args, kArguments)) {
  493. PrintUsage(kArguments);
  494. return false;
  495. }
  496. std::string selected;
  497. if (args_map.count("-filter") != 0) {
  498. selected = args_map["-filter"];
  499. }
  500. if (args_map.count("-timeout") != 0) {
  501. g_timeout_seconds = atoi(args_map["-timeout"].c_str());
  502. }
  503. bssl::UniquePtr<RSA> key(
  504. RSA_private_key_from_bytes(kDERRSAPrivate2048, kDERRSAPrivate2048Len));
  505. if (key == nullptr) {
  506. fprintf(stderr, "Failed to parse RSA key.\n");
  507. ERR_print_errors_fp(stderr);
  508. return false;
  509. }
  510. if (!SpeedRSA("RSA 2048", key.get(), selected)) {
  511. return false;
  512. }
  513. key.reset(RSA_private_key_from_bytes(kDERRSAPrivate3Prime2048,
  514. kDERRSAPrivate3Prime2048Len));
  515. if (key == nullptr) {
  516. fprintf(stderr, "Failed to parse RSA key.\n");
  517. ERR_print_errors_fp(stderr);
  518. return false;
  519. }
  520. if (!SpeedRSA("RSA 2048 (3 prime, e=3)", key.get(), selected)) {
  521. return false;
  522. }
  523. key.reset(
  524. RSA_private_key_from_bytes(kDERRSAPrivate4096, kDERRSAPrivate4096Len));
  525. if (key == nullptr) {
  526. fprintf(stderr, "Failed to parse 4096-bit RSA key.\n");
  527. ERR_print_errors_fp(stderr);
  528. return 1;
  529. }
  530. if (!SpeedRSA("RSA 4096", key.get(), selected)) {
  531. return false;
  532. }
  533. key.reset();
  534. // kTLSADLen is the number of bytes of additional data that TLS passes to
  535. // AEADs.
  536. static const size_t kTLSADLen = 13;
  537. // kLegacyADLen is the number of bytes that TLS passes to the "legacy" AEADs.
  538. // These are AEADs that weren't originally defined as AEADs, but which we use
  539. // via the AEAD interface. In order for that to work, they have some TLS
  540. // knowledge in them and construct a couple of the AD bytes internally.
  541. static const size_t kLegacyADLen = kTLSADLen - 2;
  542. if (!SpeedAEAD(EVP_aead_aes_128_gcm(), "AES-128-GCM", kTLSADLen, selected) ||
  543. !SpeedAEAD(EVP_aead_aes_256_gcm(), "AES-256-GCM", kTLSADLen, selected) ||
  544. !SpeedAEAD(EVP_aead_chacha20_poly1305(), "ChaCha20-Poly1305", kTLSADLen,
  545. selected) ||
  546. !SpeedAEAD(EVP_aead_chacha20_poly1305_old(), "ChaCha20-Poly1305-Old",
  547. kTLSADLen, selected) ||
  548. !SpeedAEAD(EVP_aead_des_ede3_cbc_sha1_tls(), "DES-EDE3-CBC-SHA1",
  549. kLegacyADLen, selected) ||
  550. !SpeedAEAD(EVP_aead_aes_128_cbc_sha1_tls(), "AES-128-CBC-SHA1",
  551. kLegacyADLen, selected) ||
  552. !SpeedAEAD(EVP_aead_aes_256_cbc_sha1_tls(), "AES-256-CBC-SHA1",
  553. kLegacyADLen, selected) ||
  554. !SpeedHash(EVP_sha1(), "SHA-1", selected) ||
  555. !SpeedHash(EVP_sha256(), "SHA-256", selected) ||
  556. !SpeedHash(EVP_sha512(), "SHA-512", selected) ||
  557. !SpeedRandom(selected) ||
  558. !SpeedECDH(selected) ||
  559. !SpeedECDSA(selected) ||
  560. !Speed25519(selected) ||
  561. !SpeedSPAKE2(selected) ||
  562. !SpeedNewHope(selected)) {
  563. return false;
  564. }
  565. return true;
  566. }