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