Purebasic apparently doesn't support AES with GCM mode. I found this C++ code to decrypt a buffer with AES-GCM using Bcrypt library.
can anyone help me translate it to PB ?
Thans you all
Code: Select all
std::string AESDecrypter(std::string EncryptedBlob, DATA_BLOB MasterKey)
{
BCRYPT_ALG_HANDLE hAlgorithm = 0;
BCRYPT_KEY_HANDLE hKey = 0;
NTSTATUS status = 0;
SIZE_T EncryptedBlobSize = EncryptedBlob.length();
SIZE_T TagOffset = EncryptedBlobSize - 15;
ULONG PlainTextSize = 0;
std::vector<BYTE> CipherPass(EncryptedBlobSize); // hold the passwords ciphertext.
std::vector<BYTE> PlainText;
std::vector<BYTE> IV(IV_SIZE); // Will hold initial vector data.
// Parse iv and password from the buffer using std::copy
std::copy(EncryptedBlob.data() + 3, EncryptedBlob.data() + 3 + IV_SIZE, IV.begin());
std::copy(EncryptedBlob.data() + 15, EncryptedBlob.data() + EncryptedBlobSize, CipherPass.begin());
// Open algorithm provider for decryption
status = BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_AES_ALGORITHM, NULL, 0);
if (!BCRYPT_SUCCESS(status))
{
std::cout << "BCryptOpenAlgorithmProvider failed with status: " << status << std::endl;
return "";
}
// Set chaining mode for decryption
status = BCryptSetProperty(hAlgorithm, BCRYPT_CHAINING_MODE, (UCHAR*)BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM), 0);
if (!BCRYPT_SUCCESS(status))
{
std::cout << "BCryptSetProperty failed with status: " << status << std::endl;
BCryptCloseAlgorithmProvider(hAlgorithm, 0);
return "";
}
// Generate symmetric key
status = BCryptGenerateSymmetricKey(hAlgorithm, &hKey, NULL, 0, MasterKey.pbData, MasterKey.cbData, 0);
if (!BCRYPT_SUCCESS(status))
{
std::cout << "BcryptGenertaeSymmetricKey failed with status: " << status << std::endl;
BCryptCloseAlgorithmProvider(hAlgorithm, 0);
return "";
}
// Auth cipher mode info
BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO AuthInfo;
BCRYPT_INIT_AUTH_MODE_INFO(AuthInfo);
TagOffset = TagOffset - 16;
AuthInfo.pbNonce = IV.data();
AuthInfo.cbNonce = IV_SIZE;
AuthInfo.pbTag = CipherPass.data() + TagOffset;
AuthInfo.cbTag = TAG_SIZE;
// Get size of plaintext buffer
status = BCryptDecrypt(hKey, CipherPass.data(), TagOffset, &AuthInfo, NULL, 0, NULL, NULL, &PlainTextSize, 0);
if (!BCRYPT_SUCCESS(status))
{
std::cout << "BCryptDecrypt (1) failed with status: " << status << std::endl;
return "";
}
// Allocate memory for the plaintext
PlainText.resize(PlainTextSize);
status = BCryptDecrypt(hKey, CipherPass.data(), TagOffset, &AuthInfo, NULL, 0, PlainText.data(), PlainTextSize, &PlainTextSize, 0);
if (!BCRYPT_SUCCESS(status))
{
std::cout << "BCrypt Decrypt (2) failed with status: " << status << std::endl;
return "";
}
// Close the algorithm handle
BCryptCloseAlgorithmProvider(hAlgorithm, 0);
return std::string(PlainText.begin(), PlainText.end());
}