Reusing a Buffer for Plaintext and Ciphertext

Reusing a Buffer for Plaintext and Ciphertext

At first sight, using the same buffer for storing plaintext and then encrypting the plaintext to produce ciphertext might seem benign. And in most cases it is. In multithreaded environments, however, it isn't. Imagine you had a race condition in your code and didn't know it. (Race conditions are conditions caused by unexpected critical dependence on the relative timing of events in software. They typically occur with synchronization errors.) Let's be frank: you never know you have a serious race condition until it's too late! Imagine also that the normal process flow of your application is as follows:

  1. Load buffer with plaintext.

  2. Encrypt buffer.

  3. Send buffer contents to the recipient.

It looks fine. However, imagine you have a multithreaded application and, for some reason, the last two stages are swapped because of a race condition:

  1. Load buffer with plaintext.

  2. Send buffer context to the recipient.

  3. Encrypt buffer.

The recipient just received some plaintext! This was a bug fixed in Internet Information Server 4. Under extreme load and rare conditions, the server would follow this pattern and send one unencrypted packet of data to the user when using SSL to protect the data channel from the server to the user. The damage potential was small: only one packet was sent to the user (or possibly an attacker). And when the user received the packet, the client software would tear down the connection. That said, the problem was fixed by Microsoft. More information about the vulnerability can be found at http://www.microsoft.com/technet/security/bulletin/MS99-053.asp.

The fix was to use two buffers, one for plaintext and the other for ciphertext, and to make sure that the ciphertext buffer was zeroed out across calls. If another race condition manifested itself, the worst outcome would be the user receiving a series of zeros, which is a better outcome than the plaintext being sent. The pseudocode for this fix looks like this:

char *bCiphertext = new char[cbCiphertext]; ZeroMemory(bCiphertext, cbCiphertext); SSLEncryptData(bPlaintext, cbPlaintext, bCiphertext, cbCiphertext); SSLSend(socket, bCiphertext, cbCiphertext); ZeroMemory(bCiphertext, cbCiphertext); delete [] bCipherText;

Never use one buffer for plaintext and ciphertext. Use two buffers, and zero out the ciphertext buffer between calls.



Writing Secure Code
Writing Secure Code, Second Edition
ISBN: 0735617228
EAN: 2147483647
Year: 2001
Pages: 286

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net