Purebasic AES - GCM encryption

Just starting out? Need help? Post your questions and find answers here.
lisa_beille
User
User
Posts: 24
Joined: Fri Dec 22, 2023 5:59 pm

Purebasic AES - GCM encryption

Post by lisa_beille »

hello all
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());
}