crypt32: CryptProtectData/CryptUnprotectData

Michael Jung mjung at
Wed May 4 03:38:40 CDT 2005

Hi Kees,

It seems to me that there is some misunderstanding involved here. I'll pick 
some comments from your previous posts and comment on them.

On Wednesday 13 April 2005 17:51, Kees Cook wrote:
> Mostly I did this because there is some optional data (description,
> entropy).  I didn't want to have to invent a data format to store all of
> that in, so I used the registry to do it instead.

You don't have to store this data. Actually it would be quite a bad idea to do 
so, for security reasons. What windows does conceptionally, is to compute a 
new key based on the following parameters: A hash of the user's login 
password, the description and the entropy. The client provided DATA_BLOB is 
then encrypted given this key and passed back to the user. It is not stored 
anywhere. In fact AFAIK, the Crypt(Un)ProtectData functions do not store 
anything whatsoever. The caller is responsible to store the encrypted 
DATA_BLOB somewhere. He also has to be able to restore in some way the 
entropy and the description, if he wants to decrypt the DATA_BLOB at some 
later time.

In my opinion, the Crypt(Un)ProtectData APIs should basically be implemented 
as no-ops at the moment (IMHO XOR-ing with some magic value is senseless in 
an open source project. I think it's not a good idea, since it gives the 
impression of security, where there is none). As far as I understand, passing 
back the input DATA_BLOB just as it was given by the caller should work just 
fine. A FIXME on the command line telling the user that his data is not 
actually protected would be appropriate. 

> - parse the Windows data format as best I can
DATA_BLOB's are opaque by nature. Applications should not expect anything of 
the format. So there is no benefit in trying to mimic the Windows data 
format. (Sometimes MSDN states that a format should be considered opaque, 
while certain components of Windows don't treat it this way. In these cases 
it's necessary to mimic the native binary format. As far as I know, that's 
not the case here.)

> - produce output that looks like the Windows data format
Same as above.

> - do some kind of encryption on the data so that nothing needs to be
>   stored to the computer between calls of CryptProtectData and
>   CryptUnprotectData.  (The existing patches intentionally avoid 
>   any encryption.
Like already said, we don't have access to a hash of the user's login 
password, so we can't provide real security here. Therefore I think we should 
not try to pretend it. IMO you should'nt do any encryption. Just pass back 

That said, if the caller actually provides the pszDataDescription and 
pOptionalEntropy parameters, you could derive a key from those. The CryptoAPI 
is accessible by the Crypt* family of API's in advapi32.dll. All that is 
necessary for this to implement should be available in wine already.

Michael Jung
mjung at

More information about the wine-devel mailing list