in lib/MessageCrypto.cc [394:459]
bool MessageCrypto::decryptData(const std::string& dataKeySecret, const proto::MessageMetadata& msgMetadata,
SharedBuffer& payload, SharedBuffer& decryptedPayload) {
// unpack iv and encrypted data
msgMetadata.encryption_param().copy(reinterpret_cast<char*>(iv_.get()),
msgMetadata.encryption_param().size());
EVP_CIPHER_CTX* cipherCtx = NULL;
decryptedPayload = SharedBuffer::allocate(payload.readableBytes() + EVP_MAX_BLOCK_LENGTH + tagLen_);
if (PULSAR_UNLIKELY(logger()->isEnabled(Logger::LEVEL_DEBUG))) {
std::string strHex = stringToHex(payload.data(), payload.readableBytes());
LOG_DEBUG(logCtx_ << "Attempting to decrypt data with encrypted size " << payload.readableBytes()
<< ", data = " << strHex);
}
if (!(cipherCtx = EVP_CIPHER_CTX_new())) {
LOG_ERROR(logCtx_ << " Failed to get cipher ctx");
return false;
}
if (!EVP_DecryptInit_ex(cipherCtx, EVP_aes_256_gcm(), NULL,
reinterpret_cast<unsigned const char*>(dataKeySecret.c_str()),
reinterpret_cast<unsigned const char*>(iv_.get()))) {
LOG_ERROR(logCtx_ << " Failed to init decrypt cipher ctx");
EVP_CIPHER_CTX_free(cipherCtx);
return false;
}
if (EVP_CIPHER_CTX_set_padding(cipherCtx, EVP_CIPH_NO_PADDING) != 1) {
LOG_ERROR(logCtx_ << " Failed to set cipher padding");
EVP_CIPHER_CTX_free(cipherCtx);
return false;
}
int cipherLen = payload.readableBytes() - tagLen_;
int decLen = 0;
if (!EVP_DecryptUpdate(cipherCtx, reinterpret_cast<unsigned char*>(decryptedPayload.mutableData()),
&decLen, reinterpret_cast<unsigned const char*>(payload.data()), cipherLen)) {
LOG_ERROR(logCtx_ << " Failed to decrypt update");
EVP_CIPHER_CTX_free(cipherCtx);
return false;
};
decryptedPayload.bytesWritten(decLen);
if (!EVP_CIPHER_CTX_ctrl(cipherCtx, EVP_CTRL_GCM_SET_TAG, tagLen_, (void*)(payload.data() + cipherLen))) {
LOG_ERROR(logCtx_ << " Failed to set gcm tag");
EVP_CIPHER_CTX_free(cipherCtx);
return false;
}
if (!EVP_DecryptFinal_ex(cipherCtx, reinterpret_cast<unsigned char*>(decryptedPayload.mutableData()),
&decLen)) {
LOG_ERROR(logCtx_ << " Failed to finalize encrypted message");
EVP_CIPHER_CTX_free(cipherCtx);
return false;
}
decryptedPayload.bytesWritten(decLen);
if (PULSAR_UNLIKELY(logger()->isEnabled(Logger::LEVEL_DEBUG))) {
std::string strHex = stringToHex(decryptedPayload.data(), decryptedPayload.readableBytes());
LOG_DEBUG(logCtx_ << "Data decrypted. Decrypted size = " << decryptedPayload.readableBytes()
<< ", data = " << strHex);
}
EVP_CIPHER_CTX_free(cipherCtx);
return true;
}