in azure-protected-vm-secrets/Windows/BcryptAesWrapper.cpp [227:323]
std::vector<unsigned char> GcmWrapper::Encrypt(const std::vector<unsigned char> &data, AesChainingInfo *chainingInfo) const
{
DWORD bytesDone = 0;
long long ciphertextSize = 0;
long long ptxOffset = 0;
if (chainingInfo == nullptr) {
throw std::exception("Chaining info must be set before calling Encrypt");
}
long long dataLength = data.size();
long long encryptedDataLength = __round_up(dataLength, this->blockLength);
long numBlocks = encryptedDataLength / this->blockLength;
GcmChainingInfo* gcmChainingInfo = dynamic_cast<GcmChainingInfo*>(chainingInfo);
BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO* authInfo = gcmChainingInfo->GetAuthInfo();
encryptedDataLength += authInfo->cbTag;
std::vector<unsigned char> result(encryptedDataLength);
std::vector<unsigned char> initVector = gcmChainingInfo->GetInitVector();
#ifndef PLATFORM_UNIX
NTSTATUS bcryptResult = STATUS_SUCCESS;
// init aad
bcryptResult = BCryptEncrypt(
this->hAesKey,
nullptr,
0,
authInfo,
initVector.data(),
initVector.size(),
nullptr,
0,
&bytesDone,
0
);
if (STATUS_SUCCESS != bcryptResult) {
// CryptographyError class, AES subclass, encryptError
throw BcryptError(bcryptResult, "BCryptEncrypt failed",
ErrorCode::CryptographyError_AES_encryptError);
}
authInfo->cbAuthData = 0;
authInfo->pbAuthData = nullptr;
for (long i = 0; i < numBlocks - 1; i++) {
bytesDone = 0;
bcryptResult = BCryptEncrypt(
this->hAesKey,
(unsigned char *)data.data() + ptxOffset,
this->blockLength,
authInfo,
initVector.data(),
initVector.size(),
result.data() + ciphertextSize,
this->blockLength,
&bytesDone,
0
);
if (STATUS_SUCCESS != bcryptResult) {
// CryptographyError class, AES subclass, encryptError
throw BcryptError(bcryptResult, "BCryptEncrypt failed",
ErrorCode::CryptographyError_AES_encryptError);
}
ciphertextSize += this->blockLength;
ptxOffset += bytesDone;
}
bytesDone = 0;
authInfo->dwFlags &= ~BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG;
bcryptResult = BCryptEncrypt(
this->hAesKey,
(unsigned char*)data.data() + ptxOffset,
data.size() - ptxOffset,
authInfo,
initVector.data(),
initVector.size(),
result.data() + ciphertextSize,
this->blockLength,
&bytesDone,
0
);
if (STATUS_SUCCESS != bcryptResult) {
// CryptographyError class, AES subclass, encryptError
throw BcryptError(bcryptResult, "BCryptEncrypt failed",
ErrorCode::CryptographyError_AES_encryptError);
}
ciphertextSize += bytesDone;
result.resize(ciphertextSize + authInfo->cbTag);
std::copy(
authInfo->pbTag,
authInfo->pbTag + authInfo->cbTag,
result.data() + ciphertextSize
);
#else
#endif // !PLATFORM_UNIX
return result;
}