/*
 * Copyright 2005 Kees Cook <kees@outflux.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */


/*
 * The Win32 CryptProtectData and CryptUnprotectData functions are meant
 * to provide a mechanism for encrypting data on a machine where other users
 * of the system can't be trusted.  It is used in many examples as a way
 * to store username and password information to the registry, but store
 * it not in the clear.
 *
 * The encryption is symmetric, but the method is unknown.  However, since
 * it is keyed to the machine and the user, it is unlikely that the values
 * would be portable.  Since programs must first call CryptProtectData to
 * get a cipher text, the underlying system doesn't have to exactly
 * match the real Windows version.  However, attempts have been made to
 * at least try to look like the Windows version, including guesses at the
 * purpose of various portions of the "opaque data blob" that is used.
 *
 */

#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "winreg.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(crypt);

#define CRYPT32_PROTECTDATA_PROV      PROV_RSA_FULL
#define CRYPT32_PROTECTDATA_HASH_CALG CALG_MD5
#define CRYPT32_PROTECTDATA_KEY_CALG  CALG_RC2
#define CRYPT32_PROTECTDATA_SALT_LEN  16

static const BYTE crypt32_protectdata_secret[] = {
    'I','\'','m',' ','h','u','n','t','i','n','g',' ',
    'w','a','b','b','i','t','s',0
};

/*
 * The data format returned by the real Windows CryptProtectData seems
 * to be something like this:

 DWORD  count0;         - how many "info0_*[16]" blocks follow (was always 1)
 BYTE   info0_0[16];    - unknown information
 ...
 DWORD  count1;         - how many "info1_*[16]" blocks follow (was always 1)
 BYTE   info1_0[16];    - unknown information
 ...
 DWORD  null0;          - NULL "end of records"?
 DWORD  str_len;        - length of WCHAR string including term
 WCHAR  str[str_len];   - The "dataDescription" value
 DWORD  unknown0;       - unknown value (seems large, but only WORD large)
 DWORD  unknown1;       - unknown value (seems small, less than a BYTE)
 DWORD  data_len;       - length of data (was 16 in samples)
 BYTE   data[data_len]; - unknown data (fingerprint?)
 DWORD  null1;          - NULL ?
 DWORD  unknown2;       - unknown value (seems large, but only WORD large)
 DWORD  unknown3;       - unknown value (seems small, less than a BYTE)
 DWORD  salt_len;       - length of salt(?) data
 BYTE   salt[salt_len]; - salt(?) for symmetric encryption
 DWORD  cipher_len;     - length of cipher(?) data - was close to plain len
 BYTE   cipher[cipher_len]; - cipher text?
 DWORD  crc_len;        - length of fingerprint(?) data - was 20 byte==160b SHA1
 BYTE   crc[crc_len];   - fingerprint of record?

 * The data structures used in Wine are modelled after this guess.
 */

struct protect_data_t
{
    DWORD       count0;
    DATA_BLOB   info0;        /* using this to hold crypt_magic_str */
    DWORD       count1;
    DATA_BLOB   info1;
    DWORD       null0;
    WCHAR *     szDataDescr;  /* serialized differently than the DATA_BLOBs */
    DWORD       unknown0;     /* perhaps the HASH alg const should go here? */
    DWORD       unknown1;
    DATA_BLOB   data0;
    DWORD       null1;
    DWORD       unknown2;     /* perhaps the KEY alg const should go here? */
    DWORD       unknown3;
    DATA_BLOB   salt;
    DATA_BLOB   cipher;
    DATA_BLOB   fingerprint;
};

/* this is used to check if an incoming structure was built by Wine */
static const char crypt_magic_str[] = "Wine Crypt32 ok";

/* debugging tool to print strings of hex chars */
static const char *
hex_str(const unsigned char *p, int n)
{
    const char * ptr;
    char report[80];
    int r=-1;
    report[0]='\0';
    ptr = wine_dbg_sprintf("%s","");
    while (--n >= 0)
    {
        if (r++ % 20 == 19)
        {
            ptr = wine_dbg_sprintf("%s%s",ptr,report);
            report[0]='\0';
        }
        sprintf(report+strlen(report),"%s%02x", r ? "," : "", *p++);
    }
    return wine_dbg_sprintf("%s%s",ptr,report);
}

#define TRACE_DATA_BLOB(blob) do { \
    TRACE("%s cbData: %u\n", #blob ,(unsigned int)((blob)->cbData)); \
    TRACE("%s pbData @ %p:%s\n", #blob ,(blob)->pbData, \
          hex_str((blob)->pbData, (blob)->cbData)); \
} while (0)

static
void serialize_dword(DWORD value,BYTE ** ptr)
{
    /*TRACE("called\n");*/

    memcpy(*ptr,&value,sizeof(DWORD));
    *ptr+=sizeof(DWORD);
}

static
void serialize_string(const BYTE *str, BYTE **ptr, DWORD len, DWORD width,
                      BOOL prepend_len)
{
    /*TRACE("called %ux%u\n",(unsigned int)len,(unsigned int)width);*/

    if (prepend_len)
    {
        serialize_dword(len,ptr);
    }
    memcpy(*ptr,str,len*width);
    *ptr+=len*width;
}

static
BOOL unserialize_dword(const BYTE *ptr, DWORD *index, DWORD size, DWORD *value)
{
    /*TRACE("called\n");*/

    if (!ptr || !index || !value) return FALSE;

    if (*index+sizeof(DWORD)>size)
    {
        return FALSE;
    }

    memcpy(value,&(ptr[*index]),sizeof(DWORD));
    *index+=sizeof(DWORD);

    return TRUE;
}

static
BOOL unserialize_string(const BYTE *ptr, DWORD *index, DWORD size,
                        DWORD len, DWORD width, BOOL inline_len,
                        BYTE ** data, DWORD * stored)
{
    /*TRACE("called\n");*/

    if (!ptr || !data) return FALSE;

    if (inline_len) {
        if (!unserialize_dword(ptr,index,size,&len))
            return FALSE;
    }

    if (*index+len*width>size)
    {
        return FALSE;
    }

    if (!(*data = CryptMemAlloc( len*width)))
    {
        return FALSE;
    }

    memcpy(*data,&(ptr[*index]),len*width);
    if (stored)
    {
        *stored = len;
    }
    *index+=len*width;

    return TRUE;
}

static
BOOL serialize(const struct protect_data_t *pInfo, DATA_BLOB *pSerial)
{
    BYTE * ptr;
    DWORD dwStrLen;
    DWORD dwStruct;

    TRACE("called\n");

    if (!pInfo || !pInfo->szDataDescr || !pSerial ||
        !pInfo->info0.pbData || !pInfo->info1.pbData ||
        !pInfo->data0.pbData || !pInfo->salt.pbData ||
        !pInfo->cipher.pbData || !pInfo->fingerprint.pbData)
    {
        return FALSE;
    }

    if (pInfo->info0.cbData!=16)
    {
        ERR("protect_data_t info0 not 16 bytes long\n");
    }

    if (pInfo->info1.cbData!=16)
    {
        ERR("protect_data_t info1 not 16 bytes long\n");
    }

    dwStrLen=lstrlenW(pInfo->szDataDescr);

    pSerial->cbData=0;
    pSerial->cbData+=sizeof(DWORD)*8; /* 8 raw DWORDs */
    pSerial->cbData+=sizeof(DWORD)*4; /* 4 BLOBs with size */
    pSerial->cbData+=pInfo->info0.cbData;
    pSerial->cbData+=pInfo->info1.cbData;
    pSerial->cbData+=(dwStrLen+1)*sizeof(WCHAR) + 4; /* str, null, size */
    pSerial->cbData+=pInfo->data0.cbData;
    pSerial->cbData+=pInfo->salt.cbData;
    pSerial->cbData+=pInfo->cipher.cbData;
    pSerial->cbData+=pInfo->fingerprint.cbData;

    /* save the actual structure size */
    dwStruct = pSerial->cbData;
    /* There may be a 256 byte minimum, but I can't prove it. */
    /*if (pSerial->cbData<256) pSerial->cbData=256;*/

    pSerial->pbData=LocalAlloc(LPTR,pSerial->cbData);
    if (!pSerial->pbData) return FALSE;

    ptr=pSerial->pbData;

    /* count0 */
    serialize_dword(pInfo->count0,&ptr);
    /*TRACE("used %u\n",ptr-pSerial->pbData);*/
    
    /* info0 */
    serialize_string(pInfo->info0.pbData,&ptr,
                     pInfo->info0.cbData,sizeof(BYTE),FALSE);
    /*TRACE("used %u\n",ptr-pSerial->pbData);*/

    /* count1 */
    serialize_dword(pInfo->count1,&ptr);
    /*TRACE("used %u\n",ptr-pSerial->pbData);*/

    /* info1 */
    serialize_string(pInfo->info1.pbData,&ptr,
                     pInfo->info1.cbData,sizeof(BYTE),FALSE);
    /*TRACE("used %u\n",ptr-pSerial->pbData);*/

    /* null0 */
    serialize_dword(pInfo->null0,&ptr);
    /*TRACE("used %u\n",ptr-pSerial->pbData);*/
    
    /* szDataDescr */
    serialize_string((BYTE*)pInfo->szDataDescr,&ptr,
                     (dwStrLen+1)*sizeof(WCHAR),sizeof(BYTE),TRUE);
    /*TRACE("used %u\n",ptr-pSerial->pbData);*/

    /* unknown0 */
    serialize_dword(pInfo->unknown0,&ptr);
    /*TRACE("used %u\n",ptr-pSerial->pbData);*/
    /* unknown1 */
    serialize_dword(pInfo->unknown1,&ptr);
    /*TRACE("used %u\n",ptr-pSerial->pbData);*/
    
    /* data0 */
    serialize_string(pInfo->data0.pbData,&ptr,
                     pInfo->data0.cbData,sizeof(BYTE),TRUE);
    /*TRACE("used %u\n",ptr-pSerial->pbData);*/

    /* null1 */
    serialize_dword(pInfo->null1,&ptr);
    /*TRACE("used %u\n",ptr-pSerial->pbData);*/
    
    /* unknown2 */
    serialize_dword(pInfo->unknown2,&ptr);
    /*TRACE("used %u\n",ptr-pSerial->pbData);*/
    /* unknown3 */
    serialize_dword(pInfo->unknown3,&ptr);
    /*TRACE("used %u\n",ptr-pSerial->pbData);*/
    
    /* salt */
    serialize_string(pInfo->salt.pbData,&ptr,
                     pInfo->salt.cbData,sizeof(BYTE),TRUE);
    /*TRACE("used %u\n",ptr-pSerial->pbData);*/

    /* cipher */
    serialize_string(pInfo->cipher.pbData,&ptr,
                     pInfo->cipher.cbData,sizeof(BYTE),TRUE);
    /*TRACE("used %u\n",ptr-pSerial->pbData);*/

    /* fingerprint */
    serialize_string(pInfo->fingerprint.pbData,&ptr,
                     pInfo->fingerprint.cbData,sizeof(BYTE),TRUE);
    /*TRACE("used %u\n",ptr-pSerial->pbData);*/

    if (ptr - pSerial->pbData != dwStruct)
    {
        ERR("struct size changed!? %u != expected %u\n",
            ptr - pSerial->pbData, (unsigned int)dwStruct);
        LocalFree(pSerial->pbData);
        pSerial->pbData=NULL;
        pSerial->cbData=0;
        return FALSE;
    }

    return TRUE;
}

static
BOOL unserialize(const DATA_BLOB *pSerial, struct protect_data_t *pInfo)
{
    BYTE * ptr;
    DWORD index;
    DWORD size;
    BOOL status=TRUE;

    TRACE("called\n");

    if (!pInfo || !pSerial || !pSerial->pbData)
        return FALSE;

    index=0;
    ptr=pSerial->pbData;
    size=pSerial->cbData;

    /* count0 */
    if (!unserialize_dword(ptr,&index,size,&pInfo->count0))
    {
        ERR("reading count0 failed!\n");
        return FALSE;
    }
    
    /* info0 */
    if (!unserialize_string(ptr,&index,size,16,sizeof(BYTE),FALSE,
                            &pInfo->info0.pbData, &pInfo->info0.cbData))
    {
        ERR("reading info0 failed!\n");
        return FALSE;
    }

    /* count1 */
    if (!unserialize_dword(ptr,&index,size,&pInfo->count1))
    {
        ERR("reading count1 failed!\n");
        return FALSE;
    }

    /* info1 */
    if (!unserialize_string(ptr,&index,size,16,sizeof(BYTE),FALSE,
                            &pInfo->info1.pbData, &pInfo->info1.cbData))
    {
        ERR("reading info1 failed!\n");
        return FALSE;
    }

    /* null0 */
    if (!unserialize_dword(ptr,&index,size,&pInfo->null0))
    {
        ERR("reading null0 failed!\n");
        return FALSE;
    }
    
    /* szDataDescr */
    if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE,
                            (BYTE**)&pInfo->szDataDescr, NULL))
    {
        ERR("reading szDataDescr failed!\n");
        return FALSE;
    }

    /* unknown0 */
    if (!unserialize_dword(ptr,&index,size,&pInfo->unknown0))
    {
        ERR("reading unknown0 failed!\n");
        return FALSE;
    }
    
    /* unknown1 */
    if (!unserialize_dword(ptr,&index,size,&pInfo->unknown1))
    {
        ERR("reading unknown1 failed!\n");
        return FALSE;
    }
    
    /* data0 */
    if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE,
                            &pInfo->data0.pbData, &pInfo->data0.cbData))
    {
        ERR("reading data0 failed!\n");
        return FALSE;
    }

    /* null1 */
    if (!unserialize_dword(ptr,&index,size,&pInfo->null1))
    {
        ERR("reading null1 failed!\n");
        return FALSE;
    }
    
    /* unknown2 */
    if (!unserialize_dword(ptr,&index,size,&pInfo->unknown2))
    {
        ERR("reading unknown2 failed!\n");
        return FALSE;
    }
    
    /* unknown3 */
    if (!unserialize_dword(ptr,&index,size,&pInfo->unknown3))
    {
        ERR("reading unknown3 failed!\n");
        return FALSE;
    }
    
    /* salt */
    if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE,
                            &pInfo->salt.pbData, &pInfo->salt.cbData))
    {
        ERR("reading salt failed!\n");
        return FALSE;
    }

    /* cipher */
    if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE,
                            &pInfo->cipher.pbData, &pInfo->cipher.cbData))
    {
        ERR("reading cipher failed!\n");
        return FALSE;
    }

    /* fingerprint */
    if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE,
                            &pInfo->fingerprint.pbData, &pInfo->fingerprint.cbData))
    {
        ERR("reading fingerprint failed!\n");
        return FALSE;
    }

    /* allow structure size to be too big (since some applications
     * will pad this up to 256 bytes, it seems) */
    if (index>size)
    {
        /* this is an impossible-to-reach test, but if the padding
         * issue is ever understood, this may become more useful */
        ERR("loaded corrupt structure! (used %u expected %u)\n",
                (unsigned int)index, (unsigned int)size);
        status=FALSE;
    }

    return status;
}

/* perform sanity checks */
static
BOOL valid_protect_data(const struct protect_data_t *pInfo)
{
    BOOL status=TRUE;

    TRACE("called\n");

    if (pInfo->count0 != 0x0001)
    {
        ERR("count0 != 0x0001 !\n");
        status=FALSE;
    }
    if (pInfo->count1 != 0x0001)
    {
        ERR("count0 != 0x0001 !\n");
        status=FALSE;
    }
    if (pInfo->null0 != 0x0000)
    {
        ERR("null0 != 0x0000 !\n");
        status=FALSE;
    }
    if (pInfo->null1 != 0x0000)
    {
        ERR("null1 != 0x0000 !\n");
        status=FALSE;
    }
    /* since we have no idea what info0 is used for, and it seems
     * rather constant, we can test for a Wine-specific magic string
     * there to be reasonably sure we're using data created by the Wine
     * implementation of CryptProtectData.
     */
    if (pInfo->info0.cbData!=strlen(crypt_magic_str)+1 ||
        strcmp( (LPCSTR)pInfo->info0.pbData,crypt_magic_str) != 0)
    {
        ERR("info0 magic value not matched !\n");
        status=FALSE;
    }

    if (!status)
    {
        ERR("unrecognized CryptProtectData block\n");
    }

    return status;
}

static
void free_protect_data(struct protect_data_t * pInfo)
{
    TRACE("called\n");

    if (!pInfo) return;

    CryptMemFree(pInfo->info0.pbData);
    CryptMemFree(pInfo->info1.pbData);
    CryptMemFree(pInfo->szDataDescr);
    CryptMemFree(pInfo->data0.pbData);
    CryptMemFree(pInfo->salt.pbData);
    CryptMemFree(pInfo->cipher.pbData);
    CryptMemFree(pInfo->fingerprint.pbData);
}

/* copies a string into a data blob */
static
BYTE *convert_str_to_blob(LPCSTR str, DATA_BLOB *blob)
{
    if (!str || !blob) return NULL;

    blob->cbData=strlen(str)+1;
    if (!(blob->pbData=CryptMemAlloc(blob->cbData)))
    {
        blob->cbData=0;
    }
    else {
        strcpy((LPSTR)blob->pbData, str);
    }

    return blob->pbData;
}

/*
 * Populates everything except "cipher" and "fingerprint".
 */
static
BOOL fill_protect_data(struct protect_data_t * pInfo, LPCWSTR szDataDescr,
                       HCRYPTPROV hProv)
{
    DWORD dwStrLen;

    TRACE("called\n");

    if (!pInfo) return FALSE;

    dwStrLen=lstrlenW(szDataDescr);

    memset(pInfo,0,sizeof(*pInfo));

    pInfo->count0=0x0001;

    convert_str_to_blob(crypt_magic_str, &pInfo->info0);

    pInfo->count1=0x0001;

    convert_str_to_blob(crypt_magic_str, &pInfo->info1);

    pInfo->null0=0x0000;

    if ((pInfo->szDataDescr=CryptMemAlloc((dwStrLen+1)*sizeof(WCHAR))))
    {
        memcpy(pInfo->szDataDescr,szDataDescr,(dwStrLen+1)*sizeof(WCHAR));
    }

    pInfo->unknown0=0x0000;
    pInfo->unknown1=0x0000;

    convert_str_to_blob(crypt_magic_str, &pInfo->data0);

    pInfo->null1=0x0000;
    pInfo->unknown2=0x0000;
    pInfo->unknown3=0x0000;

    /* allocate memory to hold a salt */
    pInfo->salt.cbData=CRYPT32_PROTECTDATA_SALT_LEN;
    if ((pInfo->salt.pbData=CryptMemAlloc(pInfo->salt.cbData)))
    {
        /* generate random salt */
        if (!CryptGenRandom(hProv, pInfo->salt.cbData, pInfo->salt.pbData))
        {
            ERR("CryptGenRandom\n");
            free_protect_data(pInfo);
            return FALSE;
        }
    }

    /* debug: show our salt */
    TRACE_DATA_BLOB(&pInfo->salt);

    pInfo->cipher.cbData=0;
    pInfo->cipher.pbData=NULL;

    pInfo->fingerprint.cbData=0;
    pInfo->fingerprint.pbData=NULL;

    /* check all the allocations at once */
    if (!pInfo->info0.pbData ||
        !pInfo->info1.pbData ||
        !pInfo->szDataDescr  ||
        !pInfo->data0.pbData ||
        !pInfo->salt.pbData
        )
    {
        ERR("could not allocate protect_data structures\n");
        free_protect_data(pInfo);
        return FALSE;
    }

    return TRUE;
}

static
BOOL convert_hash_to_blob(HCRYPTHASH hHash, DATA_BLOB * blob)
{
    DWORD dwSize;

    TRACE("called\n");

    if (!blob) return FALSE;

    dwSize=sizeof(DWORD);
    if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&blob->cbData,
                           &dwSize, 0))
    {
        ERR("failed to get hash size\n");
        return FALSE;
    }

    if (!(blob->pbData=CryptMemAlloc(blob->cbData)))
    {
        ERR("failed to allocate blob memory\n");
        return FALSE;
    }

    dwSize=blob->cbData;
    if (!CryptGetHashParam(hHash, HP_HASHVAL, blob->pbData, &dwSize, 0))
    {
        ERR("failed to get hash value\n");
        CryptMemFree(blob->pbData);
        blob->pbData=NULL;
        blob->cbData=0;
        return FALSE;
    }

    return TRUE;
}

/* test that a given hash matches an exported-to-blob hash value */
static
BOOL hash_matches_blob(HCRYPTHASH hHash, const DATA_BLOB *two)
{
    BOOL rc = FALSE;
    DATA_BLOB one;

    if (!two || !two->pbData) return FALSE;

    if (!convert_hash_to_blob(hHash,&one)) {
        return FALSE;
    }

    if ( one.cbData == two->cbData &&
         memcmp( one.pbData, two->pbData, one.cbData ) == 0 )
    {
        rc = TRUE;
    }

    CryptMemFree(one.pbData);
    return rc;
}

/* create an encryption key from a given salt and optional entropy */
static
BOOL load_encryption_key(HCRYPTPROV hProv, const DATA_BLOB *salt,
                         const DATA_BLOB *pOptionalEntropy, HCRYPTKEY *phKey)
{
    BOOL rc = TRUE;
    HCRYPTHASH hSaltHash;
    char * szUsername = NULL;
    DWORD dwUsernameLen;
    DWORD dwError;

    /* create hash for salt */
    if (!salt || !phKey ||
        !CryptCreateHash(hProv,CRYPT32_PROTECTDATA_HASH_CALG,0,0,&hSaltHash))
    {
        ERR("CryptCreateHash\n");
        return FALSE;
    }

    /* This should be the "logon credentials" instead of username */
    dwError=GetLastError();
    dwUsernameLen = 0;
    if (!GetUserNameA(NULL,&dwUsernameLen) &&
        GetLastError()==ERROR_MORE_DATA && dwUsernameLen &&
        (szUsername = CryptMemAlloc(dwUsernameLen)))
    {
        szUsername[0]='\0';
        GetUserNameA( szUsername, &dwUsernameLen );
    }
    SetLastError(dwError);

    /* salt the hash with:
     * - the user id
     * - an "internal secret"
     * - randomness (from the salt)
     * - user-supplied entropy
     */
    if ((szUsername && !CryptHashData(hSaltHash,(LPBYTE)szUsername,dwUsernameLen,0)) ||
        !CryptHashData(hSaltHash,crypt32_protectdata_secret,
                                 sizeof(crypt32_protectdata_secret)-1,0) ||
        !CryptHashData(hSaltHash,salt->pbData,salt->cbData,0) ||
        (pOptionalEntropy && !CryptHashData(hSaltHash,
                                            pOptionalEntropy->pbData,
                                            pOptionalEntropy->cbData,0)))
    {
        ERR("CryptHashData\n");
        rc = FALSE;
    }

    /* produce a symmetric key */
    if (rc && !CryptDeriveKey(hProv,CRYPT32_PROTECTDATA_KEY_CALG,
                              hSaltHash,CRYPT_EXPORTABLE,phKey))
    {
        ERR("CryptDeriveKey\n");
        rc = FALSE;
    }

    /* clean up */
    CryptDestroyHash(hSaltHash);
    CryptMemFree(szUsername);

    return rc;
}

/* debugging tool to print the structures of a ProtectData call */
static void
report(const DATA_BLOB* pDataIn, const DATA_BLOB* pOptionalEntropy,
       CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, DWORD dwFlags)
{
    TRACE("pPromptStruct: %p\n", pPromptStruct);
    if (pPromptStruct)
    {
        TRACE("  cbSize: 0x%x\n",(unsigned int)pPromptStruct->cbSize);
        TRACE("  dwPromptFlags: 0x%x\n",(unsigned int)pPromptStruct->dwPromptFlags);
        TRACE("  hwndApp: %p\n", pPromptStruct->hwndApp);
        TRACE("  szPrompt: %p %s\n",
              pPromptStruct->szPrompt,
              pPromptStruct->szPrompt ? debugstr_w(pPromptStruct->szPrompt)
              : "");
    }
    TRACE("dwFlags: 0x%04x\n",(unsigned int)dwFlags);
    TRACE_DATA_BLOB(pDataIn);
    if (pOptionalEntropy)
    {
        TRACE_DATA_BLOB(pOptionalEntropy);
        TRACE("  %s\n",debugstr_an((LPCSTR)pOptionalEntropy->pbData,pOptionalEntropy->cbData));
    }

}


/***************************************************************************
 * CryptProtectData     [CRYPT32.@]
 *
 * Generate Cipher data from given Plain and Entropy data.
 *
 * PARAMS
 *  pDataIn          [I] Plain data to be enciphered
 *  szDataDescr      [I] Optional Unicode string describing the Plain data
 *  pOptionalEntropy [I] Optional entropy data to adjust cipher, can be NULL
 *  pvReserved       [I] Reserved, must be NULL
 *  pPromptStruct    [I] Structure describing if/how to prompt during ciphering
 *  dwFlags          [I] Flags describing options to the ciphering
 *  pDataOut         [O] Resulting Cipher data, for calls to CryptUnprotectData
 *
 * RETURNS
 *  TRUE  If a Cipher was generated.
 *  FALSE If something failed and no Cipher is available.
 *
 * FIXME
 *  The true Windows encryption and keying mechanisms are unknown.
 *
 *  dwFlags and pPromptStruct are currently ignored.
 *
 * NOTES
 *  Memory allocated in pDataOut must be freed with LocalFree.
 *
 */
BOOL WINAPI CryptProtectData(DATA_BLOB* pDataIn,
                             LPCWSTR szDataDescr,
                             DATA_BLOB* pOptionalEntropy,
                             PVOID pvReserved,
                             CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct,
                             DWORD dwFlags,
                             DATA_BLOB* pDataOut)
{
    static const WCHAR empty_str[1];
    BOOL rc = FALSE;
    HCRYPTPROV hProv;
    struct protect_data_t protect_data;
    HCRYPTHASH hHash;
    HCRYPTKEY hKey;
    DWORD dwLength;

    TRACE("called\n");

    SetLastError(ERROR_SUCCESS);

    if (!pDataIn || !pDataOut)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        goto finished;
    }

    /* debug: show our arguments */
    report(pDataIn,pOptionalEntropy,pPromptStruct,dwFlags);
    TRACE("\tszDataDescr: %p %s\n", szDataDescr,
          szDataDescr ? debugstr_w(szDataDescr) : "");

    /* Windows appears to create an empty szDataDescr instead of maintaining
     * a NULL */
    if (!szDataDescr)
        szDataDescr = empty_str;

    /* get crypt context */
    if (!CryptAcquireContextW(&hProv,NULL,NULL,CRYPT32_PROTECTDATA_PROV,CRYPT_VERIFYCONTEXT))
    {
        ERR("CryptAcquireContextW failed\n");
        goto finished;
    }

    /* populate our structure */
    if (!fill_protect_data(&protect_data,szDataDescr,hProv))
    {
        ERR("fill_protect_data\n");
        goto free_context;
    }

    /* load key */
    if (!load_encryption_key(hProv,&protect_data.salt,pOptionalEntropy,&hKey))
    {
        goto free_protect_data;
    }

    /* create a hash for the encryption validation */
    if (!CryptCreateHash(hProv,CRYPT32_PROTECTDATA_HASH_CALG,0,0,&hHash))
    {
        ERR("CryptCreateHash\n");
        goto free_key;
    }

    /* calculate storage required */
    dwLength=pDataIn->cbData;
    if (CryptEncrypt(hKey, 0, TRUE, 0, pDataIn->pbData, &dwLength, 0) ||
        GetLastError()!=ERROR_MORE_DATA)
    {
        ERR("CryptEncrypt\n");
        goto free_hash;
    }
    TRACE("required encrypted storage: %u\n",(unsigned int)dwLength);

    /* copy plain text into cipher area for CryptEncrypt call */
    protect_data.cipher.cbData=dwLength;
    if (!(protect_data.cipher.pbData=CryptMemAlloc(
                                                protect_data.cipher.cbData)))
    {
        ERR("CryptMemAlloc\n");
        goto free_hash;
    }
    memcpy(protect_data.cipher.pbData,pDataIn->pbData,pDataIn->cbData);

    /* encrypt! */
    dwLength=pDataIn->cbData;
    if (!CryptEncrypt(hKey, hHash, TRUE, 0, protect_data.cipher.pbData,
                      &dwLength, protect_data.cipher.cbData))
    {
        ERR("CryptEncrypt %u\n",(unsigned int)GetLastError());
        goto free_hash;
    }
    protect_data.cipher.cbData=dwLength;

    /* debug: show the cipher */
    TRACE_DATA_BLOB(&protect_data.cipher);

    /* attach our fingerprint */
    if (!convert_hash_to_blob(hHash, &protect_data.fingerprint))
    {
        ERR("convert_hash_to_blob\n");
        goto free_hash;
    }

    /* serialize into an opaque blob */
    if (!serialize(&protect_data, pDataOut))
    {
        ERR("serialize\n");
        goto free_hash;
    }

    /* success! */
    rc=TRUE;

free_hash:
    CryptDestroyHash(hHash);
free_key:
    CryptDestroyKey(hKey);
free_protect_data:
    free_protect_data(&protect_data);
free_context:
    CryptReleaseContext(hProv,0);
finished:
    /* If some error occurred, and no error code was set, force one. */
    if (!rc && GetLastError()==ERROR_SUCCESS)
    {
        SetLastError(ERROR_INVALID_DATA);
    }

    if (rc)
    {
        SetLastError(ERROR_SUCCESS);

        TRACE_DATA_BLOB(pDataOut);
    }

    TRACE("returning %s\n", rc ? "ok" : "FAIL");

    return rc;
}


/***************************************************************************
 * CryptUnprotectData   [CRYPT32.@]
 *
 * Generate Plain data and Description from given Cipher and Entropy data.
 *
 * PARAMS
 *  pDataIn          [I] Cipher data to be decoded
 *  ppszDataDescr    [O] Optional Unicode string describing the Plain data
 *  pOptionalEntropy [I] Optional entropy data to adjust cipher, can be NULL
 *  pvReserved       [I] Reserved, must be NULL
 *  pPromptStruct    [I] Structure describing if/how to prompt during decoding
 *  dwFlags          [I] Flags describing options to the decoding
 *  pDataOut         [O] Resulting Plain data, from calls to CryptProtectData
 *
 * RETURNS
 *  TRUE  If a Plain was generated.
 *  FALSE If something failed and no Plain is available.
 *
 * FIXME
 *  The true Windows encryption and keying mechanisms are unknown.
 *
 *  dwFlags and pPromptStruct are currently ignored.
 *
 * NOTES
 *  Memory allocated in pDataOut and non-NULL ppszDataDescr must be freed
 *  with LocalFree.
 *
 */
BOOL WINAPI CryptUnprotectData(DATA_BLOB* pDataIn,
                               LPWSTR * ppszDataDescr,
                               DATA_BLOB* pOptionalEntropy,
                               PVOID pvReserved,
                               CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct,
                               DWORD dwFlags,
                               DATA_BLOB* pDataOut)
{
    BOOL rc = FALSE;

    HCRYPTPROV hProv;
    struct protect_data_t protect_data;
    HCRYPTHASH hHash;
    HCRYPTKEY hKey;
    DWORD dwLength;

    const char * announce_bad_opaque_data = "CryptUnprotectData received a DATA_BLOB that seems to have NOT been generated by Wine.  Please enable tracing ('export WINEDEBUG=crypt') to see details.";

    TRACE("called\n");

    SetLastError(ERROR_SUCCESS);

    if (!pDataIn || !pDataOut)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        goto finished;
    }

    /* debug: show our arguments */
    report(pDataIn,pOptionalEntropy,pPromptStruct,dwFlags);
    TRACE("\tppszDataDescr: %p\n", ppszDataDescr);

    /* take apart the opaque blob */
    if (!unserialize(pDataIn, &protect_data))
    {
        SetLastError(ERROR_INVALID_DATA);
        FIXME("%s\n",announce_bad_opaque_data);
        goto finished;
    }

    /* perform basic validation on the resulting structure */
    if (!valid_protect_data(&protect_data))
    {
        SetLastError(ERROR_INVALID_DATA);
        FIXME("%s\n",announce_bad_opaque_data);
        goto free_protect_data;
    }

    /* get a crypt context */
    if (!CryptAcquireContextW(&hProv,NULL,NULL,CRYPT32_PROTECTDATA_PROV,CRYPT_VERIFYCONTEXT))
    {
        ERR("CryptAcquireContextW failed\n");
        goto free_protect_data;
    }

    /* load key */
    if (!load_encryption_key(hProv,&protect_data.salt,pOptionalEntropy,&hKey))
    {
        goto free_context;
    }

    /* create a hash for the decryption validation */
    if (!CryptCreateHash(hProv,CRYPT32_PROTECTDATA_HASH_CALG,0,0,&hHash))
    {
        ERR("CryptCreateHash\n");
        goto free_key;
    }

    /* prepare for plaintext */
    pDataOut->cbData=protect_data.cipher.cbData;
    if (!(pDataOut->pbData=LocalAlloc( LPTR, pDataOut->cbData)))
    {
        ERR("CryptMemAlloc\n");
        goto free_hash;
    }
    memcpy(pDataOut->pbData,protect_data.cipher.pbData,protect_data.cipher.cbData);

    /* decrypt! */
    if (!CryptDecrypt(hKey, hHash, TRUE, 0, pDataOut->pbData,
                      &pDataOut->cbData) ||
        /* check the hash fingerprint */
        pDataOut->cbData > protect_data.cipher.cbData ||
        !hash_matches_blob(hHash, &protect_data.fingerprint))
    {
        SetLastError(ERROR_INVALID_DATA);

        LocalFree( pDataOut->pbData );
        pDataOut->pbData = NULL;
        pDataOut->cbData = 0;

        goto free_hash;
    }

    /* Copy out the description */
    dwLength = (lstrlenW(protect_data.szDataDescr)+1) * sizeof(WCHAR);
    if (ppszDataDescr)
    {
        if (!(*ppszDataDescr = LocalAlloc(LPTR,dwLength)))
        {
            ERR("LocalAlloc (ppszDataDescr)\n");
            goto free_hash;
        }
        else {
            memcpy(*ppszDataDescr,protect_data.szDataDescr,dwLength);
        }
    }

    /* success! */
    rc = TRUE;

free_hash:
    CryptDestroyHash(hHash);
free_key:
    CryptDestroyKey(hKey);
free_context:
    CryptReleaseContext(hProv,0);
free_protect_data:
    free_protect_data(&protect_data);
finished:
    /* If some error occurred, and no error code was set, force one. */
    if (!rc && GetLastError()==ERROR_SUCCESS)
    {
        SetLastError(ERROR_INVALID_DATA);
    }

    if (rc) {
        SetLastError(ERROR_SUCCESS);

        if (ppszDataDescr)
        {
            TRACE("szDataDescr: %s\n",debugstr_w(*ppszDataDescr));
        }
        TRACE_DATA_BLOB(pDataOut);
    }

    TRACE("returning %s\n", rc ? "ok" : "FAIL");

    return rc;
}
