Home > Net >  DPAPI output buffer memory management
DPAPI output buffer memory management

Time:10-26

I'm using CryptProtectData() and CryptUnprotectData() APIs for data encryption and decryption in my App.

Reading the API documentation, it's not clear why LocalFree() needs to be called against the output buffer after usage. The example code on that page does not invoke LocalFree(), is that a miss?

What's also missing in the documentation (the main reason for this question) is that, how is DATA_BLOB::pbData for the output managed by DPAPI? Can I manage the memory for the output buffer myself? If I can, how do I know the output buffer size of the encrypted data in advance so that I can allocate a large enough buffer for CryptProtectData() or CryptUnprotectData() to use?

Here is a code snippet on how I'm using CryptProtectData():

DATA_BLOB dataIn;
DATA_BLOB dataOut;
dataIn.pbData = (BYTE *)"Hello world";
dataIn.cbData = (DWORD)strlen((char*)pbDataInput);

if(CryptProtectData(&dataIn, NULL, NULL, NULL, NULL, 0, &dataOut))
{
    printf("Encrypted data size: %d", dataOut.cbData);
    // LocalFree(dataOut.pbData); // Is this needed? Why? How do I manage dataOut.pbData by myself?
}

CodePudding user response:

Reading the API documentation, it's not clear why LocalFree() needs to be called against the output buffer after usage.

Because CryptProtectData() dynamically allocates an output buffer and gives it to you, so you need to free it when you are done using it.

The example code on that page does not invoke LocalFree(), is that a miss?

Yes.

how is DATA_BLOB::pbData for the output managed by DPAPI? Can I manage the memory for the output buffer myself?

Not with CryptProtectData(), no. You must use the buffer that it gives you.

If you want to use your own buffer, use CryptProtectMemory() instead.

If I can, how do I know the output buffer size of the encrypted data in advance so that I can allocate a large enough buffer for CryptProtectData() or CryptUnprotectData() to use?

CryptProtectData() handles that for you when it allocates the dynamic output buffer.

CryptProtectMemory() encrypts inline, using the same buffer for both input and output. So you are responsible for ensuring that the buffer is large enough to hold the output. Its documentation says:

[in] cbDataIn

Number of bytes of memory pointed to by the pData parameter to encrypt. The number of bytes must be a multiple of the CRYPTPROTECTMEMORY_BLOCK_SIZE constant defined in Wincrypt.h.

So, you would simply take the size of your input data and round it up to the next multiple of the block size.

  • Related