foundationdb/flowbench/BenchEncrypt.cpp
Ata E Husain Bohra 591ef57857
Upgrade AES 128 GCM -> AES 256, StreamCipher code refactor (#6314)
* Upgrade AES 128 GCM -> AES 256, StreamCipher code refactor

Major changes proposed are:
1. Refactor StreamCipher code to enable instantiation of
   multiple encryption keys. However, code still retains
   a globalEncryption key semantics used in Backup file
   encryption usecase.
2. Enhance StreamCipher to provide HMAC signature digest
   generation. Further, the class implements HMAC encryption
   key derivation function.
3. Upgrade StreamCipher to use AES 256 GCM mode from currently
   supported AES 128 GCM mode.
   Note: The code changes the encryption key size, however, the
         feature is NOT currently in use, hence, should be OK.
3. Add EncryptionOps validation and benchmark toml supported
   workload, it does the following:
   a. Allow user to configure encrypt-decrypt of a fixed size
      buffer or variable size buffer [100, 512K]
   b. Allow user to configure number of interactions of the runs,
      in each iteration: generate random data, derive an encryption
      key using HMAC SHA256 method, encrypt data and
      then decrypt data. It collects following metrics:
    i) time taken to derive encryption key.
    ii) time taken to encrypt the buffer.
    iii) time taken to decrypt the buffer.
    iv) total bytes encrypted and/or decrypted
   c. Along with stats it basic basic validations on the encrypted
      and decrypted buffer
   d. On completion for test, records the above mentioned metrics
      in trace files.
2022-01-31 19:52:44 -06:00

80 lines
2.8 KiB
C++

/*
* BenchEncrypt.cpp
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2013-2020 Apple Inc. and the FoundationDB project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "benchmark/benchmark.h"
#include "flow/StreamCipher.h"
#include "flowbench/GlobalData.h"
static StreamCipher::IV getRandomIV() {
StreamCipher::IV iv;
generateRandomData(iv.data(), iv.size());
return iv;
}
static inline Standalone<StringRef> encrypt(const StreamCipherKey* const key,
const StreamCipher::IV& iv,
unsigned char const* data,
size_t len) {
EncryptionStreamCipher encryptor(key, iv);
Arena arena;
auto encrypted = encryptor.encrypt(data, len, arena);
return Standalone<StringRef>(encrypted, arena);
}
static void bench_encrypt(benchmark::State& state) {
auto bytes = state.range(0);
auto chunks = state.range(1);
auto chunkSize = bytes / chunks;
StreamCipherKey::initializeGlobalRandomTestKey();
auto key = StreamCipherKey::getGlobalCipherKey();
auto iv = getRandomIV();
auto data = getKey(bytes);
while (state.KeepRunning()) {
for (int chunk = 0; chunk < chunks; ++chunk) {
benchmark::DoNotOptimize(encrypt(key, iv, data.begin() + chunk * chunkSize, chunkSize));
}
}
state.SetBytesProcessed(bytes * static_cast<long>(state.iterations()));
}
static void bench_decrypt(benchmark::State& state) {
auto bytes = state.range(0);
auto chunks = state.range(1);
auto chunkSize = bytes / chunks;
StreamCipherKey::initializeGlobalRandomTestKey();
auto key = StreamCipherKey::getGlobalCipherKey();
auto iv = getRandomIV();
auto data = getKey(bytes);
auto encrypted = encrypt(key, iv, data.begin(), data.size());
while (state.KeepRunning()) {
Arena arena;
DecryptionStreamCipher decryptor(key, iv);
for (int chunk = 0; chunk < chunks; ++chunk) {
benchmark::DoNotOptimize(
Standalone<StringRef>(decryptor.decrypt(encrypted.begin() + chunk * chunkSize, chunkSize, arena)));
}
}
state.SetBytesProcessed(bytes * static_cast<long>(state.iterations()));
}
BENCHMARK(bench_encrypt)->Ranges({ { 1 << 12, 1 << 20 }, { 1, 1 << 12 } });
BENCHMARK(bench_decrypt)->Ranges({ { 1 << 12, 1 << 20 }, { 1, 1 << 12 } });