2021-01-23 13:46:36 +08:00
|
|
|
/*
|
|
|
|
* StreamCipher.actor.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 "flow/StreamCipher.h"
|
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-02-01 09:52:44 +08:00
|
|
|
#include "flow/Arena.h"
|
|
|
|
#include "flow/ITrace.h"
|
2021-01-23 13:46:36 +08:00
|
|
|
#include "flow/UnitTest.h"
|
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-02-01 09:52:44 +08:00
|
|
|
#include <memory>
|
2021-01-23 13:46:36 +08:00
|
|
|
|
2021-02-04 13:30:20 +08:00
|
|
|
std::unordered_set<EVP_CIPHER_CTX*> StreamCipher::ctxs;
|
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-02-01 09:52:44 +08:00
|
|
|
std::unordered_set<StreamCipherKey*> StreamCipherKey::cipherKeys;
|
|
|
|
std::unique_ptr<StreamCipherKey> StreamCipherKey::globalKey;
|
2021-02-04 09:39:59 +08:00
|
|
|
|
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-02-01 09:52:44 +08:00
|
|
|
bool StreamCipherKey::isGlobalKeyPresent() {
|
|
|
|
return StreamCipherKey::globalKey.get() != nullptr;
|
2021-01-23 13:46:36 +08:00
|
|
|
}
|
|
|
|
|
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-02-01 09:52:44 +08:00
|
|
|
void StreamCipherKey::allocGlobalCipherKey() {
|
|
|
|
if (StreamCipherKey::isGlobalKeyPresent()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
StreamCipherKey::globalKey = std::make_unique<StreamCipherKey>(AES_256_KEY_LENGTH);
|
|
|
|
StreamCipherKey::cipherKeys.insert(StreamCipherKey::globalKey.get());
|
2021-02-04 13:30:20 +08:00
|
|
|
}
|
|
|
|
|
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-02-01 09:52:44 +08:00
|
|
|
void StreamCipherKey::initializeGlobalRandomTestKey() {
|
|
|
|
if (!StreamCipherKey::isGlobalKeyPresent()) {
|
|
|
|
StreamCipherKey::allocGlobalCipherKey();
|
|
|
|
}
|
|
|
|
StreamCipherKey::globalKey.get()->initializeRandomTestKey();
|
2021-02-04 13:30:20 +08:00
|
|
|
}
|
|
|
|
|
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-02-01 09:52:44 +08:00
|
|
|
StreamCipherKey const* StreamCipherKey::getGlobalCipherKey() {
|
|
|
|
if (!StreamCipherKey::isGlobalKeyPresent()) {
|
|
|
|
StreamCipherKey::allocGlobalCipherKey();
|
2021-02-04 13:30:20 +08:00
|
|
|
}
|
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-02-01 09:52:44 +08:00
|
|
|
ASSERT(StreamCipherKey::isGlobalKeyPresent());
|
|
|
|
return globalKey.get();
|
2021-02-04 13:30:20 +08:00
|
|
|
}
|
|
|
|
|
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-02-01 09:52:44 +08:00
|
|
|
void StreamCipherKey::cleanup() noexcept {
|
|
|
|
for (auto cipherKey : cipherKeys) {
|
|
|
|
cipherKey->reset();
|
2021-06-27 08:38:57 +08:00
|
|
|
}
|
2021-06-26 05:11:21 +08:00
|
|
|
}
|
|
|
|
|
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-02-01 09:52:44 +08:00
|
|
|
void StreamCipherKey::initializeKey(uint8_t* data, int len) {
|
|
|
|
memset(arr.get(), 0, keySize);
|
|
|
|
int copyLen = std::min(keySize, len);
|
|
|
|
memcpy(arr.get(), data, copyLen);
|
|
|
|
}
|
|
|
|
|
|
|
|
StreamCipherKey::StreamCipherKey(int size) : arr(std::make_unique<uint8_t[]>(size)), keySize(size) {
|
|
|
|
memset(arr.get(), 0, keySize);
|
|
|
|
cipherKeys.insert(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
StreamCipherKey::~StreamCipherKey() {
|
|
|
|
reset();
|
|
|
|
cipherKeys.erase(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
StreamCipher::StreamCipher(int keySize)
|
|
|
|
: ctx(EVP_CIPHER_CTX_new()), hmacCtx(HMAC_CTX_new()), cipherKey(std::make_unique<StreamCipherKey>(keySize)) {
|
|
|
|
ctxs.insert(ctx);
|
2021-02-04 13:30:20 +08:00
|
|
|
}
|
|
|
|
|
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-02-01 09:52:44 +08:00
|
|
|
StreamCipher::StreamCipher()
|
|
|
|
: ctx(EVP_CIPHER_CTX_new()), hmacCtx(HMAC_CTX_new()),
|
|
|
|
cipherKey(std::make_unique<StreamCipherKey>(AES_256_KEY_LENGTH)) {
|
|
|
|
ctxs.insert(ctx);
|
2021-02-04 13:30:20 +08:00
|
|
|
}
|
|
|
|
|
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-02-01 09:52:44 +08:00
|
|
|
StreamCipher::~StreamCipher() {
|
|
|
|
HMAC_CTX_free(hmacCtx);
|
|
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
|
|
ctxs.erase(ctx);
|
2021-06-26 05:11:21 +08:00
|
|
|
}
|
|
|
|
|
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-02-01 09:52:44 +08:00
|
|
|
EVP_CIPHER_CTX* StreamCipher::getCtx() {
|
|
|
|
return ctx;
|
2021-06-26 05:11:21 +08:00
|
|
|
}
|
|
|
|
|
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-02-01 09:52:44 +08:00
|
|
|
HMAC_CTX* StreamCipher::getHmacCtx() {
|
|
|
|
return hmacCtx;
|
2021-02-04 13:30:20 +08:00
|
|
|
}
|
|
|
|
|
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-02-01 09:52:44 +08:00
|
|
|
void StreamCipher::cleanup() noexcept {
|
|
|
|
for (auto ctx : ctxs) {
|
|
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void applyHmacKeyDerivationFunc(StreamCipherKey* cipherKey, HmacSha256StreamCipher* hmacGenerator, Arena& arena) {
|
|
|
|
uint8_t buf[cipherKey->size() + sizeof(uint64_t)];
|
|
|
|
memcpy(&buf[0], cipherKey->data(), cipherKey->size());
|
|
|
|
uint64_t seed = deterministicRandom()->randomUInt64();
|
|
|
|
memcpy(&buf[0] + cipherKey->size(), &seed, sizeof(uint64_t));
|
|
|
|
StringRef digest = hmacGenerator->digest(&buf[0], cipherKey->size() + sizeof(uint64_t), arena);
|
|
|
|
std::copy(digest.begin(), digest.end(), &buf[0]);
|
|
|
|
cipherKey->initializeKey(&buf[0], cipherKey->size());
|
2021-02-04 13:30:20 +08:00
|
|
|
}
|
|
|
|
|
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-02-01 09:52:44 +08:00
|
|
|
EncryptionStreamCipher::EncryptionStreamCipher(const StreamCipherKey* key, const StreamCipher::IV& iv)
|
|
|
|
: cipher(StreamCipher(key->size())) {
|
|
|
|
EVP_EncryptInit_ex(cipher.getCtx(), EVP_aes_256_gcm(), nullptr, nullptr, nullptr);
|
2021-02-04 13:30:20 +08:00
|
|
|
EVP_CIPHER_CTX_ctrl(cipher.getCtx(), EVP_CTRL_AEAD_SET_IVLEN, iv.size(), nullptr);
|
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-02-01 09:52:44 +08:00
|
|
|
EVP_EncryptInit_ex(cipher.getCtx(), nullptr, nullptr, key->data(), iv.data());
|
2021-01-23 13:46:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
StringRef EncryptionStreamCipher::encrypt(unsigned char const* plaintext, int len, Arena& arena) {
|
2021-07-22 09:02:51 +08:00
|
|
|
TEST(true); // Encrypting data with StreamCipher
|
2021-01-23 13:46:36 +08:00
|
|
|
auto ciphertext = new (arena) unsigned char[len + AES_BLOCK_SIZE];
|
|
|
|
int bytes{ 0 };
|
2021-02-04 13:30:20 +08:00
|
|
|
EVP_EncryptUpdate(cipher.getCtx(), ciphertext, &bytes, plaintext, len);
|
2021-01-23 13:46:36 +08:00
|
|
|
return StringRef(ciphertext, bytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
StringRef EncryptionStreamCipher::finish(Arena& arena) {
|
|
|
|
auto ciphertext = new (arena) unsigned char[AES_BLOCK_SIZE];
|
|
|
|
int bytes{ 0 };
|
2021-02-04 13:30:20 +08:00
|
|
|
EVP_EncryptFinal_ex(cipher.getCtx(), ciphertext, &bytes);
|
2021-01-23 13:46:36 +08:00
|
|
|
return StringRef(ciphertext, bytes);
|
|
|
|
}
|
|
|
|
|
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-02-01 09:52:44 +08:00
|
|
|
DecryptionStreamCipher::DecryptionStreamCipher(const StreamCipherKey* key, const StreamCipher::IV& iv)
|
|
|
|
: cipher(key->size()) {
|
|
|
|
EVP_DecryptInit_ex(cipher.getCtx(), EVP_aes_256_gcm(), nullptr, nullptr, nullptr);
|
2021-02-04 13:30:20 +08:00
|
|
|
EVP_CIPHER_CTX_ctrl(cipher.getCtx(), EVP_CTRL_AEAD_SET_IVLEN, iv.size(), nullptr);
|
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-02-01 09:52:44 +08:00
|
|
|
EVP_DecryptInit_ex(cipher.getCtx(), nullptr, nullptr, key->data(), iv.data());
|
2021-01-23 13:46:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
StringRef DecryptionStreamCipher::decrypt(unsigned char const* ciphertext, int len, Arena& arena) {
|
2021-07-22 09:02:51 +08:00
|
|
|
TEST(true); // Decrypting data with StreamCipher
|
2021-01-23 13:46:36 +08:00
|
|
|
auto plaintext = new (arena) unsigned char[len];
|
|
|
|
int bytesDecrypted{ 0 };
|
2021-02-04 13:30:20 +08:00
|
|
|
EVP_DecryptUpdate(cipher.getCtx(), plaintext, &bytesDecrypted, ciphertext, len);
|
2021-01-23 13:46:36 +08:00
|
|
|
int finalBlockBytes{ 0 };
|
2021-02-04 13:30:20 +08:00
|
|
|
EVP_DecryptFinal_ex(cipher.getCtx(), plaintext + bytesDecrypted, &finalBlockBytes);
|
2021-01-23 13:46:36 +08:00
|
|
|
return StringRef(plaintext, bytesDecrypted + finalBlockBytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
StringRef DecryptionStreamCipher::finish(Arena& arena) {
|
|
|
|
auto plaintext = new (arena) unsigned char[AES_BLOCK_SIZE];
|
|
|
|
int finalBlockBytes{ 0 };
|
2021-02-04 13:30:20 +08:00
|
|
|
EVP_DecryptFinal_ex(cipher.getCtx(), plaintext, &finalBlockBytes);
|
2021-01-23 13:46:36 +08:00
|
|
|
return StringRef(plaintext, finalBlockBytes);
|
|
|
|
}
|
|
|
|
|
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-02-01 09:52:44 +08:00
|
|
|
HmacSha256StreamCipher::HmacSha256StreamCipher() : cipher(EVP_MAX_KEY_LENGTH) {
|
|
|
|
HMAC_Init_ex(cipher.getHmacCtx(), NULL, 0, EVP_sha256(), nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
StringRef HmacSha256StreamCipher::digest(unsigned char const* data, int len, Arena& arena) {
|
|
|
|
TEST(true); // Digest using StreamCipher
|
|
|
|
unsigned int digestLen = HMAC_size(cipher.getHmacCtx());
|
|
|
|
auto digest = new (arena) unsigned char[digestLen];
|
|
|
|
HMAC_Update(cipher.getHmacCtx(), data, len);
|
|
|
|
HMAC_Final(cipher.getHmacCtx(), digest, &digestLen);
|
|
|
|
return StringRef(digest, digestLen);
|
|
|
|
}
|
|
|
|
|
|
|
|
StringRef HmacSha256StreamCipher::finish(Arena& arena) {
|
|
|
|
unsigned int digestLen = HMAC_size(cipher.getHmacCtx());
|
|
|
|
auto digest = new (arena) unsigned char[digestLen];
|
|
|
|
HMAC_Final(cipher.getHmacCtx(), digest, &digestLen);
|
|
|
|
return StringRef(digest, digestLen);
|
|
|
|
}
|
|
|
|
|
2021-07-07 12:20:59 +08:00
|
|
|
// Only used to link unit tests
|
2021-01-23 13:46:36 +08:00
|
|
|
void forceLinkStreamCipherTests() {}
|
|
|
|
|
2021-03-29 13:14:37 +08:00
|
|
|
// Tests both encryption and decryption of random data
|
|
|
|
// using the StreamCipher class
|
2021-01-23 13:46:36 +08:00
|
|
|
TEST_CASE("flow/StreamCipher") {
|
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-02-01 09:52:44 +08:00
|
|
|
StreamCipherKey::initializeGlobalRandomTestKey();
|
|
|
|
StreamCipherKey const* key = StreamCipherKey::getGlobalCipherKey();
|
2021-01-23 13:46:36 +08:00
|
|
|
|
2021-01-23 13:47:36 +08:00
|
|
|
StreamCipher::IV iv;
|
2021-01-23 13:46:36 +08:00
|
|
|
generateRandomData(iv.data(), iv.size());
|
|
|
|
|
|
|
|
Arena arena;
|
|
|
|
std::vector<unsigned char> plaintext(deterministicRandom()->randomInt(0, 10001));
|
|
|
|
generateRandomData(&plaintext.front(), plaintext.size());
|
|
|
|
std::vector<unsigned char> ciphertext(plaintext.size() + AES_BLOCK_SIZE);
|
|
|
|
std::vector<unsigned char> decryptedtext(plaintext.size() + AES_BLOCK_SIZE);
|
|
|
|
|
|
|
|
TraceEvent("StreamCipherTestStart")
|
|
|
|
.detail("PlaintextSize", plaintext.size())
|
|
|
|
.detail("AESBlockSize", AES_BLOCK_SIZE);
|
|
|
|
{
|
2021-01-23 13:47:36 +08:00
|
|
|
EncryptionStreamCipher encryptor(key, iv);
|
2021-01-23 13:46:36 +08:00
|
|
|
int index = 0;
|
|
|
|
int encryptedOffset = 0;
|
|
|
|
while (index < plaintext.size()) {
|
|
|
|
const auto chunkSize = std::min<int>(deterministicRandom()->randomInt(1, 101), plaintext.size() - index);
|
|
|
|
const auto encrypted = encryptor.encrypt(&plaintext[index], chunkSize, arena);
|
|
|
|
TraceEvent("StreamCipherTestEcryptedChunk")
|
|
|
|
.detail("EncryptedSize", encrypted.size())
|
|
|
|
.detail("EncryptedOffset", encryptedOffset)
|
|
|
|
.detail("Index", index);
|
|
|
|
std::copy(encrypted.begin(), encrypted.end(), &ciphertext[encryptedOffset]);
|
|
|
|
encryptedOffset += encrypted.size();
|
|
|
|
index += chunkSize;
|
|
|
|
}
|
|
|
|
const auto encrypted = encryptor.finish(arena);
|
|
|
|
std::copy(encrypted.begin(), encrypted.end(), &ciphertext[encryptedOffset]);
|
|
|
|
ciphertext.resize(encryptedOffset + encrypted.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2021-01-23 13:47:36 +08:00
|
|
|
DecryptionStreamCipher decryptor(key, iv);
|
2021-01-23 13:46:36 +08:00
|
|
|
int index = 0;
|
|
|
|
int decryptedOffset = 0;
|
|
|
|
while (index < plaintext.size()) {
|
|
|
|
const auto chunkSize = std::min<int>(deterministicRandom()->randomInt(1, 101), plaintext.size() - index);
|
|
|
|
const auto decrypted = decryptor.decrypt(&ciphertext[index], chunkSize, arena);
|
|
|
|
TraceEvent("StreamCipherTestDecryptedChunk")
|
|
|
|
.detail("DecryptedSize", decrypted.size())
|
|
|
|
.detail("DecryptedOffset", decryptedOffset)
|
|
|
|
.detail("Index", index);
|
|
|
|
std::copy(decrypted.begin(), decrypted.end(), &decryptedtext[decryptedOffset]);
|
|
|
|
decryptedOffset += decrypted.size();
|
|
|
|
index += chunkSize;
|
|
|
|
}
|
|
|
|
const auto decrypted = decryptor.finish(arena);
|
|
|
|
std::copy(decrypted.begin(), decrypted.end(), &decryptedtext[decryptedOffset]);
|
2021-06-27 02:15:12 +08:00
|
|
|
ASSERT_EQ(decryptedOffset + decrypted.size(), plaintext.size());
|
2021-01-23 13:46:36 +08:00
|
|
|
decryptedtext.resize(decryptedOffset + decrypted.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT(plaintext == decryptedtext);
|
|
|
|
return Void();
|
|
|
|
}
|