21.03.2013 Views

Problem - Kevin Tafuro

Problem - Kevin Tafuro

Problem - Kevin Tafuro

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

encryption and decryption can be done incrementally, but there is only a single<br />

function for each.<br />

The CryptEncrypt( ) function is used to encrypt data all at once or incrementally. As<br />

a convenience, the function can also pass the plaintext to be encrypted to a hash<br />

object to compute the hash as data is passed through for encryption. CryptEncrypt( )<br />

can be somewhat tricky to use because it places the resulting ciphertext into the<br />

same buffer as the plaintext. If you’re using a stream cipher, this is no problem<br />

because the ciphertext is usually the same size as the plaintext, but if you’re using a<br />

block cipher, the ciphertext can be up to a whole block longer than the plaintext.<br />

The following convenience function handles the buffering issues transparently for<br />

you. It requires the spc_memcpy( ) function from Recipe 13.2.<br />

BYTE *SpcEncrypt(HCRYPTKEY hKey, BOOL bFinal, BYTE *pbData, DWORD *cbData) {<br />

BYTE *pbResult;<br />

DWORD dwBlockLen, dwDataLen;<br />

ALG_ID Algid;<br />

dwDataLen = sizeof(ALG_ID);<br />

if (!CryptGetKeyParam(hKey, KP_ALGID, (BYTE *)&Algid, &dwDataLen, 0)) return 0;<br />

if (GET_ALG_TYPE(Algid) != ALG_TYPE_STREAM) {<br />

dwDataLen = sizeof(DWORD);<br />

if (!CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE *)&dwBlockLen, &dwDataLen, 0))<br />

return 0;<br />

dwDataLen = ((*cbData + (dwBlockLen * 2) - 1) / dwBlockLen) * dwBlockLen;<br />

if (!(pbResult = (BYTE *)LocalAlloc(LMEM_FIXED, dwDataLen))) return 0;<br />

CopyMemory(pbResult, pbData, *cbData);<br />

if (!CryptEncrypt(hKey, 0, bFinal, 0, pbResult, &dwDataLen, *cbData)) {<br />

LocalFree(pbResult);<br />

return 0;<br />

}<br />

*cbData = dwDataLen;<br />

return pbResult;<br />

}<br />

if (!(pbResult = (BYTE *)LocalAlloc(LMEM_FIXED, *cbData))) return 0;<br />

CopyMemory(pbResult, pbData, *cbData);<br />

if (!CryptEncrypt(hKey, 0, bFinal, 0, pbResult, cbData, *cbData)) {<br />

LocalFree(pbResult);<br />

return 0;<br />

}<br />

return pbResult;<br />

}<br />

The return from SpcEncrypt( ) will be a buffer allocated with LocalAlloc( ) that contains<br />

the ciphertext version of the plaintext that’s passed as an argument into the<br />

function as pbData. If the function fails for some reason, the return from the function<br />

will be NULL, and a call to GetLastError( ) will return the error code. This function<br />

has the following arguments:<br />

242 | Chapter 5: Symmetric Encryption<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!