Add an option to configure bssl speed chunk size.
bsaes, in its current incarnation, hits various pathological behaviors at different input sizes. Make it easy to experiment around them. Bug: 256 Change-Id: Ib6c6ca7d06a570dbf7d4d2ea81c1db0d94d3d0c4 Reviewed-on: https://boringssl-review.googlesource.com/c/34876 Commit-Queue: David Benjamin <davidben@google.com> Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
98ad4d77e3
commit
6443173d03
123
tool/speed.cc
123
tool/speed.cc
@ -19,6 +19,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -98,6 +99,7 @@ static uint64_t time_now() {
|
||||
#endif
|
||||
|
||||
static uint64_t g_timeout_seconds = 1;
|
||||
static std::vector<size_t> g_chunk_lengths = {16, 256, 1350, 8192};
|
||||
|
||||
static bool TimeFunction(TimeResults *results, std::function<bool()> func) {
|
||||
// total_us is the total amount of time that we'll aim to measure a function
|
||||
@ -274,10 +276,19 @@ static bool SpeedRSAKeyGen(const std::string &selected) {
|
||||
(static_cast<double>(num_calls) / us) * 1000000);
|
||||
const size_t n = durations.size();
|
||||
assert(n > 0);
|
||||
|
||||
// |min| and |max| must be stored in temporary variables to avoid an MSVC
|
||||
// bug on x86. There, size_t is a typedef for unsigned, but MSVC's printf
|
||||
// warning tries to retain the distinction and suggest %zu for size_t
|
||||
// instead of %u. It gets confused if std::vector<unsigned> and
|
||||
// std::vector<size_t> are both instantiated. Being typedefs, the two
|
||||
// instantiations are identical, which somehow breaks the size_t vs unsigned
|
||||
// metadata.
|
||||
unsigned min = durations[0];
|
||||
unsigned median = n & 1 ? durations[n / 2]
|
||||
: (durations[n / 2 - 1] + durations[n / 2]) / 2;
|
||||
printf(" min: %uus, median: %uus, max: %uus\n", durations[0], median,
|
||||
durations[n - 1]);
|
||||
unsigned max = durations[n - 1];
|
||||
printf(" min: %uus, median: %uus, max: %uus\n", min, median, max);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -289,11 +300,19 @@ static uint8_t *align(uint8_t *in, unsigned alignment) {
|
||||
~static_cast<size_t>(alignment - 1));
|
||||
}
|
||||
|
||||
static bool SpeedAEADChunk(const EVP_AEAD *aead, const std::string &name,
|
||||
static std::string ChunkLenSuffix(size_t chunk_len) {
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), " (%zu byte%s)", chunk_len,
|
||||
chunk_len != 1 ? "s" : "");
|
||||
return buf;
|
||||
}
|
||||
|
||||
static bool SpeedAEADChunk(const EVP_AEAD *aead, std::string name,
|
||||
size_t chunk_len, size_t ad_len,
|
||||
evp_aead_direction_t direction) {
|
||||
static const unsigned kAlignment = 16;
|
||||
|
||||
name += ChunkLenSuffix(chunk_len);
|
||||
bssl::ScopedEVP_AEAD_CTX ctx;
|
||||
const size_t key_len = EVP_AEAD_key_length(aead);
|
||||
const size_t nonce_len = EVP_AEAD_nonce_length(aead);
|
||||
@ -390,12 +409,12 @@ static bool SpeedAEAD(const EVP_AEAD *aead, const std::string &name,
|
||||
return true;
|
||||
}
|
||||
|
||||
return SpeedAEADChunk(aead, name + " (16 bytes)", 16, ad_len,
|
||||
evp_aead_seal) &&
|
||||
SpeedAEADChunk(aead, name + " (1350 bytes)", 1350, ad_len,
|
||||
evp_aead_seal) &&
|
||||
SpeedAEADChunk(aead, name + " (8192 bytes)", 8192, ad_len,
|
||||
evp_aead_seal);
|
||||
for (size_t chunk_len : g_chunk_lengths) {
|
||||
if (!SpeedAEADChunk(aead, name, chunk_len, ad_len, evp_aead_seal)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SpeedAEADOpen(const EVP_AEAD *aead, const std::string &name,
|
||||
@ -404,15 +423,16 @@ static bool SpeedAEADOpen(const EVP_AEAD *aead, const std::string &name,
|
||||
return true;
|
||||
}
|
||||
|
||||
return SpeedAEADChunk(aead, name + " (16 bytes)", 16, ad_len,
|
||||
evp_aead_open) &&
|
||||
SpeedAEADChunk(aead, name + " (1350 bytes)", 1350, ad_len,
|
||||
evp_aead_open) &&
|
||||
SpeedAEADChunk(aead, name + " (8192 bytes)", 8192, ad_len,
|
||||
evp_aead_open);
|
||||
for (size_t chunk_len : g_chunk_lengths) {
|
||||
if (!SpeedAEADChunk(aead, name, chunk_len, ad_len, evp_aead_open)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SpeedHashChunk(const EVP_MD *md, const std::string &name,
|
||||
static bool SpeedHashChunk(const EVP_MD *md, std::string name,
|
||||
size_t chunk_len) {
|
||||
bssl::ScopedEVP_MD_CTX ctx;
|
||||
uint8_t scratch[8192];
|
||||
@ -421,6 +441,7 @@ static bool SpeedHashChunk(const EVP_MD *md, const std::string &name,
|
||||
return false;
|
||||
}
|
||||
|
||||
name += ChunkLenSuffix(chunk_len);
|
||||
TimeResults results;
|
||||
if (!TimeFunction(&results, [&ctx, md, chunk_len, &scratch]() -> bool {
|
||||
uint8_t digest[EVP_MAX_MD_SIZE];
|
||||
@ -438,24 +459,30 @@ static bool SpeedHashChunk(const EVP_MD *md, const std::string &name,
|
||||
results.PrintWithBytes(name, chunk_len);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SpeedHash(const EVP_MD *md, const std::string &name,
|
||||
const std::string &selected) {
|
||||
if (!selected.empty() && name.find(selected) == std::string::npos) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return SpeedHashChunk(md, name + " (16 bytes)", 16) &&
|
||||
SpeedHashChunk(md, name + " (256 bytes)", 256) &&
|
||||
SpeedHashChunk(md, name + " (8192 bytes)", 8192);
|
||||
for (size_t chunk_len : g_chunk_lengths) {
|
||||
if (!SpeedHashChunk(md, name, chunk_len)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SpeedRandomChunk(const std::string &name, size_t chunk_len) {
|
||||
static bool SpeedRandomChunk(std::string name, size_t chunk_len) {
|
||||
uint8_t scratch[8192];
|
||||
|
||||
if (chunk_len > sizeof(scratch)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
name += ChunkLenSuffix(chunk_len);
|
||||
TimeResults results;
|
||||
if (!TimeFunction(&results, [chunk_len, &scratch]() -> bool {
|
||||
RAND_bytes(scratch, chunk_len);
|
||||
@ -473,9 +500,13 @@ static bool SpeedRandom(const std::string &selected) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return SpeedRandomChunk("RNG (16 bytes)", 16) &&
|
||||
SpeedRandomChunk("RNG (256 bytes)", 256) &&
|
||||
SpeedRandomChunk("RNG (8192 bytes)", 8192);
|
||||
for (size_t chunk_len : g_chunk_lengths) {
|
||||
if (!SpeedRandomChunk("RNG", chunk_len)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SpeedECDHCurve(const std::string &name, int nid,
|
||||
@ -802,15 +833,25 @@ static bool SpeedHRSS(const std::string &selected) {
|
||||
|
||||
static const struct argument kArguments[] = {
|
||||
{
|
||||
"-filter", kOptionalArgument,
|
||||
"A filter on the speed tests to run",
|
||||
"-filter",
|
||||
kOptionalArgument,
|
||||
"A filter on the speed tests to run",
|
||||
},
|
||||
{
|
||||
"-timeout", kOptionalArgument,
|
||||
"The number of seconds to run each test for (default is 1)",
|
||||
"-timeout",
|
||||
kOptionalArgument,
|
||||
"The number of seconds to run each test for (default is 1)",
|
||||
},
|
||||
{
|
||||
"", kOptionalArgument, "",
|
||||
"-chunks",
|
||||
kOptionalArgument,
|
||||
"A comma-separated list of input sizes to run tests at (default is "
|
||||
"16,256,1350,8192)",
|
||||
},
|
||||
{
|
||||
"",
|
||||
kOptionalArgument,
|
||||
"",
|
||||
},
|
||||
};
|
||||
|
||||
@ -830,6 +871,32 @@ bool Speed(const std::vector<std::string> &args) {
|
||||
g_timeout_seconds = atoi(args_map["-timeout"].c_str());
|
||||
}
|
||||
|
||||
if (args_map.count("-chunks") != 0) {
|
||||
g_chunk_lengths.clear();
|
||||
const char *start = args_map["-chunks"].data();
|
||||
const char *end = start + args_map["-chunks"].size();
|
||||
while (start != end) {
|
||||
errno = 0;
|
||||
char *ptr;
|
||||
unsigned long long val = strtoull(start, &ptr, 10);
|
||||
if (ptr == start /* no numeric characters found */ ||
|
||||
errno == ERANGE /* overflow */ ||
|
||||
static_cast<size_t>(val) != val) {
|
||||
fprintf(stderr, "Error parsing -chunks argument\n");
|
||||
return false;
|
||||
}
|
||||
g_chunk_lengths.push_back(static_cast<size_t>(val));
|
||||
start = ptr;
|
||||
if (start != end) {
|
||||
if (*start != ',') {
|
||||
fprintf(stderr, "Error parsing -chunks argument\n");
|
||||
return false;
|
||||
}
|
||||
start++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// kTLSADLen is the number of bytes of additional data that TLS passes to
|
||||
// AEADs.
|
||||
static const size_t kTLSADLen = 13;
|
||||
|
Loading…
Reference in New Issue
Block a user