in util/EncryptionUtils.cpp [277:332]
bool AESEncryptor::start(const EncryptionParams& encryptionData,
std::string& ivOut) {
WDT_CHECK(!started_);
// reset the enc ctx
// To reuse the same ctx, we have to have different reset code for different
// openssl version. So, we will just create another ctx for simplification
evpCtx_.reset(createAndInitCtx());
type_ = encryptionData.getType();
const std::string& key = encryptionData.getSecret();
if (key.length() != kAESBlockSize) {
WLOG(ERROR) << "Encryption key size must be " << kAESBlockSize
<< ", but input size length " << key.length();
return false;
}
ivOut.resize(kAESBlockSize);
uint8_t* ivPtr = (uint8_t*)(&ivOut.front());
uint8_t* keyPtr = (uint8_t*)(&key.front());
if (RAND_bytes(ivPtr, kAESBlockSize) != 1) {
WLOG(ERROR)
<< "RAND_bytes failed, unable to generate initialization vector";
return false;
}
const EVP_CIPHER* cipher = getCipher(type_);
if (cipher == nullptr) {
return false;
}
int cipherBlockSize = EVP_CIPHER_block_size(cipher);
WDT_CHECK_EQ(1, cipherBlockSize);
// Not super clear this is actually needed - but probably if not set
// gcm only uses 96 out of the 128 bits of IV. Let's use all of it to
// reduce chances of attacks on large data transfers.
if (type_ == ENC_AES128_GCM) {
if (EVP_EncryptInit_ex(evpCtx_.get(), cipher, nullptr, nullptr, nullptr) !=
1) {
WLOG(ERROR) << "GCM First init error";
}
if (EVP_CIPHER_CTX_ctrl(evpCtx_.get(), EVP_CTRL_GCM_SET_IVLEN, ivOut.size(),
nullptr) != 1) {
WLOG(ERROR) << "Encrypt Init ivlen set failed";
}
}
if (EVP_EncryptInit_ex(evpCtx_.get(), cipher, nullptr, keyPtr, ivPtr) != 1) {
WLOG(ERROR) << "Encrypt Init failed";
return false;
}
started_ = true;
return true;
}