Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
 
 

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