ReactOS 0.4.15-dev-7942-gd23573b
protectdata.c File Reference
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "wine/debug.h"
Include dependency graph for protectdata.c:

Go to the source code of this file.

Classes

struct  protect_data_t
 

Macros

#define CRYPT32_PROTECTDATA_PROV   PROV_RSA_FULL
 
#define CRYPT32_PROTECTDATA_HASH_CALG   CALG_SHA1
 
#define CRYPT32_PROTECTDATA_HASH_LEN   160
 
#define CRYPT32_PROTECTDATA_KEY_CALG   CALG_3DES
 
#define CRYPT32_PROTECTDATA_KEY_LEN   168
 
#define CRYPT32_PROTECTDATA_SALT_LEN   16
 
#define TRACE_DATA_BLOB(blob)
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (crypt)
 
static const charhex_str (const unsigned char *p, int n)
 
static void serialize_dword (DWORD value, BYTE **ptr)
 
static void serialize_string (const BYTE *str, BYTE **ptr, DWORD len, DWORD width, BOOL prepend_len)
 
static BOOL unserialize_dword (const BYTE *ptr, DWORD *index, DWORD size, DWORD *value)
 
static BOOL unserialize_string (const BYTE *ptr, DWORD *index, DWORD size, DWORD len, DWORD width, BOOL inline_len, BYTE **data, DWORD *stored)
 
static BOOL serialize (const struct protect_data_t *pInfo, DATA_BLOB *pSerial)
 
static BOOL unserialize (const DATA_BLOB *pSerial, struct protect_data_t *pInfo)
 
static BOOL valid_protect_data (const struct protect_data_t *pInfo)
 
static void free_protect_data (struct protect_data_t *pInfo)
 
static BYTEconvert_str_to_blob (LPCSTR str, DATA_BLOB *blob)
 
static BOOL fill_protect_data (struct protect_data_t *pInfo, LPCWSTR szDataDescr, HCRYPTPROV hProv)
 
static BOOL convert_hash_to_blob (HCRYPTHASH hHash, DATA_BLOB *blob)
 
static BOOL hash_matches_blob (HCRYPTHASH hHash, const DATA_BLOB *two)
 
static BOOL load_encryption_key (HCRYPTPROV hProv, DWORD key_len, const DATA_BLOB *salt, const DATA_BLOB *pOptionalEntropy, HCRYPTKEY *phKey)
 
static void report (const DATA_BLOB *pDataIn, const DATA_BLOB *pOptionalEntropy, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD dwFlags)
 
BOOL WINAPI CryptProtectData (DATA_BLOB *pDataIn, LPCWSTR szDataDescr, DATA_BLOB *pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD dwFlags, DATA_BLOB *pDataOut)
 
BOOL WINAPI CryptUnprotectData (DATA_BLOB *pDataIn, LPWSTR *ppszDataDescr, DATA_BLOB *pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD dwFlags, DATA_BLOB *pDataOut)
 

Variables

static const BYTE crypt32_protectdata_secret []
 
static const char crypt_magic_str [] = "Wine Crypt32 ok"
 

Macro Definition Documentation

◆ CRYPT32_PROTECTDATA_HASH_CALG

#define CRYPT32_PROTECTDATA_HASH_CALG   CALG_SHA1

Definition at line 50 of file protectdata.c.

◆ CRYPT32_PROTECTDATA_HASH_LEN

#define CRYPT32_PROTECTDATA_HASH_LEN   160

Definition at line 51 of file protectdata.c.

◆ CRYPT32_PROTECTDATA_KEY_CALG

#define CRYPT32_PROTECTDATA_KEY_CALG   CALG_3DES

Definition at line 52 of file protectdata.c.

◆ CRYPT32_PROTECTDATA_KEY_LEN

#define CRYPT32_PROTECTDATA_KEY_LEN   168

Definition at line 53 of file protectdata.c.

◆ CRYPT32_PROTECTDATA_PROV

#define CRYPT32_PROTECTDATA_PROV   PROV_RSA_FULL

Definition at line 49 of file protectdata.c.

◆ CRYPT32_PROTECTDATA_SALT_LEN

#define CRYPT32_PROTECTDATA_SALT_LEN   16

Definition at line 54 of file protectdata.c.

◆ TRACE_DATA_BLOB

#define TRACE_DATA_BLOB (   blob)
Value:
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 const char * hex_str(const unsigned char *p, int n)
Definition: protectdata.c:116
Definition: image.c:134
_In_ HCRYPTHASH _In_ BOOL _In_ DWORD _Inout_updates_bytes_to_ pdwDataLen BYTE * pbData
Definition: wincrypt.h:4201

Definition at line 135 of file protectdata.c.

Function Documentation

◆ convert_hash_to_blob()

static BOOL convert_hash_to_blob ( HCRYPTHASH  hHash,
DATA_BLOB blob 
)
static

Definition at line 645 of file protectdata.c.

646{
648
649 TRACE("called\n");
650
651 if (!blob) return FALSE;
652
653 dwSize=sizeof(DWORD);
654 if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&blob->cbData,
655 &dwSize, 0))
656 {
657 ERR("failed to get hash size\n");
658 return FALSE;
659 }
660
661 if (!(blob->pbData=CryptMemAlloc(blob->cbData)))
662 {
663 ERR("failed to allocate blob memory\n");
664 return FALSE;
665 }
666
667 dwSize=blob->cbData;
668 if (!CryptGetHashParam(hHash, HP_HASHVAL, blob->pbData, &dwSize, 0))
669 {
670 ERR("failed to get hash value\n");
671 CryptMemFree(blob->pbData);
672 blob->pbData=NULL;
673 blob->cbData=0;
674 return FALSE;
675 }
676
677 return TRUE;
678}
#define ERR(fmt,...)
Definition: debug.h:110
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI CryptGetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
Definition: crypt.c:1610
LPVOID WINAPI CryptMemAlloc(ULONG cbSize)
Definition: main.c:131
VOID WINAPI CryptMemFree(LPVOID pv)
Definition: main.c:141
unsigned long DWORD
Definition: ntddk_ex.h:95
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define DWORD
Definition: nt_native.h:44
#define TRACE(s)
Definition: solgame.cpp:4
#define HP_HASHSIZE
Definition: wincrypt.h:2184
_In_ HCRYPTHASH hHash
Definition: wincrypt.h:4198
#define HP_HASHVAL
Definition: wincrypt.h:2183
unsigned char BYTE
Definition: xxhash.c:193

Referenced by CryptProtectData(), and hash_matches_blob().

◆ convert_str_to_blob()

static BYTE * convert_str_to_blob ( LPCSTR  str,
DATA_BLOB blob 
)
static

Definition at line 551 of file protectdata.c.

552{
553 if (!str || !blob) return NULL;
554
555 blob->cbData=strlen(str)+1;
556 if (!(blob->pbData=CryptMemAlloc(blob->cbData)))
557 {
558 blob->cbData=0;
559 }
560 else {
561 strcpy((LPSTR)blob->pbData, str);
562 }
563
564 return blob->pbData;
565}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
const WCHAR * str
char * LPSTR
Definition: xmlstorage.h:182

Referenced by fill_protect_data().

◆ CryptProtectData()

BOOL WINAPI CryptProtectData ( DATA_BLOB pDataIn,
LPCWSTR  szDataDescr,
DATA_BLOB pOptionalEntropy,
PVOID  pvReserved,
CRYPTPROTECT_PROMPTSTRUCT pPromptStruct,
DWORD  dwFlags,
DATA_BLOB pDataOut 
)

Definition at line 821 of file protectdata.c.

828{
829 static const WCHAR empty_str[1];
830 BOOL rc = FALSE;
832 struct protect_data_t protect_data;
836
837 TRACE("called\n");
838
840
841 if (!pDataIn || !pDataOut)
842 {
844 goto finished;
845 }
846
847 /* debug: show our arguments */
848 report(pDataIn,pOptionalEntropy,pPromptStruct,dwFlags);
849 TRACE("\tszDataDescr: %p %s\n", szDataDescr,
851
852 /* Windows appears to create an empty szDataDescr instead of maintaining
853 * a NULL */
854 if (!szDataDescr)
856
857 /* get crypt context */
859 {
860 ERR("CryptAcquireContextW failed\n");
861 goto finished;
862 }
863
864 /* populate our structure */
865 if (!fill_protect_data(&protect_data,szDataDescr,hProv))
866 {
867 ERR("fill_protect_data\n");
868 goto free_context;
869 }
870
871 /* load key */
872 if (!load_encryption_key(hProv,protect_data.cipher_key_len,&protect_data.salt,pOptionalEntropy,&hKey))
873 {
875 }
876
877 /* create a hash for the encryption validation */
879 {
880 ERR("CryptCreateHash\n");
881 goto free_key;
882 }
883
884 /* calculate storage required */
885 dwLength=pDataIn->cbData;
886 if (CryptEncrypt(hKey, 0, TRUE, 0, pDataIn->pbData, &dwLength, 0) ||
888 {
889 ERR("CryptEncrypt\n");
890 goto free_hash;
891 }
892 TRACE("required encrypted storage: %u\n", dwLength);
893
894 /* copy plain text into cipher area for CryptEncrypt call */
895 protect_data.cipher.cbData=dwLength;
896 if (!(protect_data.cipher.pbData=CryptMemAlloc(
897 protect_data.cipher.cbData)))
898 {
899 ERR("CryptMemAlloc\n");
900 goto free_hash;
901 }
902 memcpy(protect_data.cipher.pbData,pDataIn->pbData,pDataIn->cbData);
903
904 /* encrypt! */
905 dwLength=pDataIn->cbData;
906 if (!CryptEncrypt(hKey, hHash, TRUE, 0, protect_data.cipher.pbData,
907 &dwLength, protect_data.cipher.cbData))
908 {
909 ERR("CryptEncrypt %u\n", GetLastError());
910 goto free_hash;
911 }
912 protect_data.cipher.cbData=dwLength;
913
914 /* debug: show the cipher */
915 TRACE_DATA_BLOB(&protect_data.cipher);
916
917 /* attach our fingerprint */
918 if (!convert_hash_to_blob(hHash, &protect_data.fingerprint))
919 {
920 ERR("convert_hash_to_blob\n");
921 goto free_hash;
922 }
923
924 /* serialize into an opaque blob */
925 if (!serialize(&protect_data, pDataOut))
926 {
927 ERR("serialize\n");
928 goto free_hash;
929 }
930
931 /* success! */
932 rc=TRUE;
933
934free_hash:
936free_key:
939 free_protect_data(&protect_data);
940free_context:
942finished:
943 /* If some error occurred, and no error code was set, force one. */
944 if (!rc && GetLastError()==ERROR_SUCCESS)
945 {
947 }
948
949 if (rc)
950 {
952
953 TRACE_DATA_BLOB(pDataOut);
954 }
955
956 TRACE("returning %s\n", rc ? "ok" : "FAIL");
957
958 return rc;
959}
static const TCHAR empty_str[]
Definition: dialog.c:20
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL WINAPI CryptCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash)
Definition: crypt.c:740
BOOL WINAPI CryptDestroyKey(HCRYPTKEY hKey)
Definition: crypt.c:930
BOOL WINAPI CryptDestroyHash(HCRYPTHASH hHash)
Definition: crypt.c:890
BOOL WINAPI CryptReleaseContext(HCRYPTPROV hProv, DWORD dwFlags)
Definition: crypt.c:648
BOOL WINAPI CryptAcquireContextW(HCRYPTPROV *phProv, LPCWSTR pszContainer, LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
Definition: crypt.c:358
BOOL WINAPI CryptEncrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen)
Definition: crypt.c:1093
#define CRYPT32_PROTECTDATA_HASH_CALG
Definition: protectdata.c:50
#define CRYPT32_PROTECTDATA_PROV
Definition: protectdata.c:49
static BOOL fill_protect_data(struct protect_data_t *pInfo, LPCWSTR szDataDescr, HCRYPTPROV hProv)
Definition: protectdata.c:571
static void report(const DATA_BLOB *pDataIn, const DATA_BLOB *pOptionalEntropy, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD dwFlags)
Definition: protectdata.c:769
static void free_protect_data(struct protect_data_t *pInfo)
Definition: protectdata.c:534
static BOOL convert_hash_to_blob(HCRYPTHASH hHash, DATA_BLOB *blob)
Definition: protectdata.c:645
static BOOL serialize(const struct protect_data_t *pInfo, DATA_BLOB *pSerial)
Definition: protectdata.c:217
static BOOL load_encryption_key(HCRYPTPROV hProv, DWORD key_len, const DATA_BLOB *salt, const DATA_BLOB *pOptionalEntropy, HCRYPTKEY *phKey)
Definition: protectdata.c:705
#define TRACE_DATA_BLOB(blob)
Definition: protectdata.c:135
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
static DWORD DWORD * dwLength
Definition: fusion.c:86
unsigned int BOOL
Definition: ntddk_ex.h:94
FxAutoRegKey hKey
#define debugstr_w
Definition: kernel32.h:32
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static HCRYPTPROV hProv
Definition: rsaenh.c:32
BYTE * pbData
Definition: wincrypt.h:103
WCHAR * szDataDescr
Definition: protectdata.c:99
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CRYPT_VERIFYCONTEXT
Definition: wincrypt.h:2069
ULONG_PTR HCRYPTPROV
Definition: wincrypt.h:46
ULONG_PTR HCRYPTHASH
Definition: wincrypt.h:50
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
static const WCHAR MS_ENHANCED_PROV_W[]
Definition: wincrypt.h:1882
ULONG_PTR HCRYPTKEY
Definition: wincrypt.h:49
#define ERROR_INVALID_DATA
Definition: winerror.h:116
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by store_key_pair().

◆ CryptUnprotectData()

BOOL WINAPI CryptUnprotectData ( DATA_BLOB pDataIn,
LPWSTR ppszDataDescr,
DATA_BLOB pOptionalEntropy,
PVOID  pvReserved,
CRYPTPROTECT_PROMPTSTRUCT pPromptStruct,
DWORD  dwFlags,
DATA_BLOB pDataOut 
)

Definition at line 990 of file protectdata.c.

997{
998 BOOL rc = FALSE;
999
1001 struct protect_data_t protect_data;
1005
1006 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.";
1007
1008 TRACE("called\n");
1009
1011
1012 if (!pDataIn || !pDataOut)
1013 {
1015 goto finished;
1016 }
1017 if (!pDataIn->cbData)
1018 {
1020 goto finished;
1021 }
1022
1023 /* debug: show our arguments */
1024 report(pDataIn,pOptionalEntropy,pPromptStruct,dwFlags);
1025 TRACE("\tppszDataDescr: %p\n", ppszDataDescr);
1026
1027 /* take apart the opaque blob */
1028 if (!unserialize(pDataIn, &protect_data))
1029 {
1031 FIXME("%s\n",announce_bad_opaque_data);
1032 goto finished;
1033 }
1034
1035 /* perform basic validation on the resulting structure */
1036 if (!valid_protect_data(&protect_data))
1037 {
1039 FIXME("%s\n",announce_bad_opaque_data);
1040 goto free_protect_data;
1041 }
1042
1043 /* get a crypt context */
1045 {
1046 ERR("CryptAcquireContextW failed\n");
1047 goto free_protect_data;
1048 }
1049
1050 /* load key */
1051 if (!load_encryption_key(hProv,protect_data.cipher_key_len,&protect_data.salt,pOptionalEntropy,&hKey))
1052 {
1053 goto free_context;
1054 }
1055
1056 /* create a hash for the decryption validation */
1058 {
1059 ERR("CryptCreateHash\n");
1060 goto free_key;
1061 }
1062
1063 /* prepare for plaintext */
1064 pDataOut->cbData=protect_data.cipher.cbData;
1065 if (!(pDataOut->pbData=LocalAlloc( LPTR, pDataOut->cbData)))
1066 {
1067 ERR("CryptMemAlloc\n");
1068 goto free_hash;
1069 }
1070 memcpy(pDataOut->pbData,protect_data.cipher.pbData,protect_data.cipher.cbData);
1071
1072 /* decrypt! */
1073 if (!CryptDecrypt(hKey, hHash, TRUE, 0, pDataOut->pbData,
1074 &pDataOut->cbData) ||
1075 /* check the hash fingerprint */
1076 pDataOut->cbData > protect_data.cipher.cbData ||
1077 !hash_matches_blob(hHash, &protect_data.fingerprint))
1078 {
1080
1081 LocalFree( pDataOut->pbData );
1082 pDataOut->pbData = NULL;
1083 pDataOut->cbData = 0;
1084
1085 goto free_hash;
1086 }
1087
1088 /* Copy out the description */
1089 dwLength = (lstrlenW(protect_data.szDataDescr)+1) * sizeof(WCHAR);
1090 if (ppszDataDescr)
1091 {
1092 if (!(*ppszDataDescr = LocalAlloc(LPTR,dwLength)))
1093 {
1094 ERR("LocalAlloc (ppszDataDescr)\n");
1095 goto free_hash;
1096 }
1097 else {
1098 memcpy(*ppszDataDescr,protect_data.szDataDescr,dwLength);
1099 }
1100 }
1101
1102 /* success! */
1103 rc = TRUE;
1104
1105free_hash:
1107free_key:
1109free_context:
1112 free_protect_data(&protect_data);
1113finished:
1114 /* If some error occurred, and no error code was set, force one. */
1115 if (!rc && GetLastError()==ERROR_SUCCESS)
1116 {
1118 }
1119
1120 if (rc) {
1122
1123 if (ppszDataDescr)
1124 {
1125 TRACE("szDataDescr: %s\n",debugstr_w(*ppszDataDescr));
1126 }
1127 TRACE_DATA_BLOB(pDataOut);
1128 }
1129
1130 TRACE("returning %s\n", rc ? "ok" : "FAIL");
1131
1132 return rc;
1133}
#define FIXME(fmt,...)
Definition: debug.h:111
BOOL WINAPI CryptDecrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
Definition: crypt.c:800
static BOOL valid_protect_data(const struct protect_data_t *pInfo)
Definition: protectdata.c:487
static BOOL hash_matches_blob(HCRYPTHASH hHash, const DATA_BLOB *two)
Definition: protectdata.c:682
static BOOL unserialize(const DATA_BLOB *pSerial, struct protect_data_t *pInfo)
Definition: protectdata.c:344
#define lstrlenW
Definition: compat.h:750
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
#define LPTR
Definition: winbase.h:381

Referenced by read_key_value().

◆ fill_protect_data()

static BOOL fill_protect_data ( struct protect_data_t pInfo,
LPCWSTR  szDataDescr,
HCRYPTPROV  hProv 
)
static

Definition at line 571 of file protectdata.c.

573{
574 DWORD dwStrLen;
575
576 TRACE("called\n");
577
578 if (!pInfo) return FALSE;
579
580 dwStrLen=lstrlenW(szDataDescr);
581
582 memset(pInfo,0,sizeof(*pInfo));
583
584 pInfo->count0=0x0001;
585
587
588 pInfo->count1=0x0001;
589
591
592 pInfo->null0=0x0000;
593
594 if ((pInfo->szDataDescr=CryptMemAlloc((dwStrLen+1)*sizeof(WCHAR))))
595 {
596 memcpy(pInfo->szDataDescr,szDataDescr,(dwStrLen+1)*sizeof(WCHAR));
597 }
598
601
603
604 pInfo->null1=0x0000;
607
608 /* allocate memory to hold a salt */
610 {
611 /* generate random salt */
613 {
614 ERR("CryptGenRandom\n");
615 free_protect_data(pInfo);
616 return FALSE;
617 }
619 /* debug: show our salt */
620 TRACE_DATA_BLOB(&pInfo->salt);
621 }
622 pInfo->cipher.cbData=0;
623 pInfo->cipher.pbData=NULL;
624
625 pInfo->fingerprint.cbData=0;
626 pInfo->fingerprint.pbData=NULL;
627
628 /* check all the allocations at once */
629 if (!pInfo->info0.pbData ||
630 !pInfo->info1.pbData ||
631 !pInfo->szDataDescr ||
632 !pInfo->data0.pbData ||
633 !pInfo->salt.pbData
634 )
635 {
636 ERR("could not allocate protect_data structures\n");
637 free_protect_data(pInfo);
638 return FALSE;
639 }
640
641 return TRUE;
642}
BOOL WINAPI CryptGenRandom(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer)
Definition: crypt.c:700
#define CRYPT32_PROTECTDATA_KEY_LEN
Definition: protectdata.c:53
#define CRYPT32_PROTECTDATA_SALT_LEN
Definition: protectdata.c:54
#define CRYPT32_PROTECTDATA_KEY_CALG
Definition: protectdata.c:52
#define CRYPT32_PROTECTDATA_HASH_LEN
Definition: protectdata.c:51
static const char crypt_magic_str[]
Definition: protectdata.c:112
static BYTE * convert_str_to_blob(LPCSTR str, DATA_BLOB *blob)
Definition: protectdata.c:551
#define memset(x, y, z)
Definition: compat.h:39
DATA_BLOB data0
Definition: protectdata.c:102
DATA_BLOB info0
Definition: protectdata.c:95
DATA_BLOB cipher
Definition: protectdata.c:107
DATA_BLOB info1
Definition: protectdata.c:97
ALG_ID cipher_alg
Definition: protectdata.c:100
DATA_BLOB salt
Definition: protectdata.c:106
DATA_BLOB fingerprint
Definition: protectdata.c:108
DWORD cipher_key_len
Definition: protectdata.c:101

Referenced by CryptProtectData().

◆ free_protect_data()

static void free_protect_data ( struct protect_data_t pInfo)
static

Definition at line 534 of file protectdata.c.

535{
536 TRACE("called\n");
537
538 if (!pInfo) return;
539
540 CryptMemFree(pInfo->info0.pbData);
541 CryptMemFree(pInfo->info1.pbData);
543 CryptMemFree(pInfo->data0.pbData);
544 CryptMemFree(pInfo->salt.pbData);
545 CryptMemFree(pInfo->cipher.pbData);
547}

Referenced by CryptProtectData(), CryptUnprotectData(), and fill_protect_data().

◆ hash_matches_blob()

static BOOL hash_matches_blob ( HCRYPTHASH  hHash,
const DATA_BLOB two 
)
static

Definition at line 682 of file protectdata.c.

683{
684 BOOL rc = FALSE;
686
687 if (!two || !two->pbData) return FALSE;
688
690 return FALSE;
691 }
692
693 if ( one.cbData == two->cbData &&
694 memcmp( one.pbData, two->pbData, one.cbData ) == 0 )
695 {
696 rc = TRUE;
697 }
698
699 CryptMemFree(one.pbData);
700 return rc;
701}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
static double two
Definition: jn_yn.c:52
int one
Definition: sehframes.cpp:28

Referenced by CryptUnprotectData().

◆ hex_str()

static const char * hex_str ( const unsigned char p,
int  n 
)
static

Definition at line 116 of file protectdata.c.

117{
118 const char * ptr;
119 char report[80];
120 int r=-1;
121 report[0]='\0';
122 ptr = wine_dbg_sprintf("%s","");
123 while (--n >= 0)
124 {
125 if (r++ % 20 == 19)
126 {
127 ptr = wine_dbg_sprintf("%s%s",ptr,report);
128 report[0]='\0';
129 }
130 sprintf(report+strlen(report),"%s%02x", r ? "," : "", *p++);
131 }
132 return wine_dbg_sprintf("%s%s",ptr,report);
133}
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:296
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
GLfloat GLfloat p
Definition: glext.h:8902
static PVOID ptr
Definition: dispmode.c:27
#define sprintf(buf, format,...)
Definition: sprintf.c:55

◆ load_encryption_key()

static BOOL load_encryption_key ( HCRYPTPROV  hProv,
DWORD  key_len,
const DATA_BLOB salt,
const DATA_BLOB pOptionalEntropy,
HCRYPTKEY phKey 
)
static

Definition at line 705 of file protectdata.c.

707{
708 BOOL rc = TRUE;
709 HCRYPTHASH hSaltHash;
710 char * szUsername = NULL;
711 DWORD dwUsernameLen;
712 DWORD dwError;
713
714 /* create hash for salt */
715 if (!salt || !phKey ||
717 {
718 ERR("CryptCreateHash\n");
719 return FALSE;
720 }
721
722 /* This should be the "logon credentials" instead of username */
723 dwError=GetLastError();
724 dwUsernameLen = 0;
725 if (!GetUserNameA(NULL, &dwUsernameLen) &&
726 GetLastError() == ERROR_INSUFFICIENT_BUFFER && dwUsernameLen &&
727 (szUsername = CryptMemAlloc(dwUsernameLen)))
728 {
729 szUsername[0]='\0';
730 GetUserNameA( szUsername, &dwUsernameLen );
731 }
732 SetLastError(dwError);
733
734 /* salt the hash with:
735 * - the user id
736 * - an "internal secret"
737 * - randomness (from the salt)
738 * - user-supplied entropy
739 */
740 if ((szUsername && !CryptHashData(hSaltHash,(LPBYTE)szUsername,dwUsernameLen,0)) ||
742 sizeof(crypt32_protectdata_secret)-1,0) ||
743 !CryptHashData(hSaltHash,salt->pbData,salt->cbData,0) ||
744 (pOptionalEntropy && !CryptHashData(hSaltHash,
745 pOptionalEntropy->pbData,
746 pOptionalEntropy->cbData,0)))
747 {
748 ERR("CryptHashData\n");
749 rc = FALSE;
750 }
751
752 /* produce a symmetric key */
754 hSaltHash,key_len << 16 | CRYPT_EXPORTABLE,phKey))
755 {
756 ERR("CryptDeriveKey\n");
757 rc = FALSE;
758 }
759
760 /* clean up */
761 CryptDestroyHash(hSaltHash);
762 CryptMemFree(szUsername);
763
764 return rc;
765}
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
BOOL WINAPI GetUserNameA(LPSTR lpszName, LPDWORD lpSize)
Definition: misc.c:246
BOOL WINAPI CryptHashData(HCRYPTHASH hHash, const BYTE *pbData, DWORD dwDataLen, DWORD dwFlags)
Definition: crypt.c:1771
BOOL WINAPI CryptDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, DWORD dwFlags, HCRYPTKEY *phKey)
Definition: crypt.c:838
static const BYTE crypt32_protectdata_secret[]
Definition: protectdata.c:56
unsigned char * LPBYTE
Definition: typedefs.h:53
#define CRYPT_EXPORTABLE
Definition: wincrypt.h:2206

Referenced by CryptProtectData(), and CryptUnprotectData().

◆ report()

static void report ( const DATA_BLOB pDataIn,
const DATA_BLOB pOptionalEntropy,
CRYPTPROTECT_PROMPTSTRUCT pPromptStruct,
DWORD  dwFlags 
)
static

Definition at line 769 of file protectdata.c.

771{
772 TRACE("pPromptStruct: %p\n", pPromptStruct);
773 if (pPromptStruct)
774 {
775 TRACE(" cbSize: 0x%x\n", pPromptStruct->cbSize);
776 TRACE(" dwPromptFlags: 0x%x\n", pPromptStruct->dwPromptFlags);
777 TRACE(" hwndApp: %p\n", pPromptStruct->hwndApp);
778 TRACE(" szPrompt: %p %s\n",
779 pPromptStruct->szPrompt,
780 pPromptStruct->szPrompt ? debugstr_w(pPromptStruct->szPrompt)
781 : "");
782 }
783 TRACE("dwFlags: 0x%04x\n", dwFlags);
784 TRACE_DATA_BLOB(pDataIn);
785 if (pOptionalEntropy)
786 {
787 TRACE_DATA_BLOB(pOptionalEntropy);
788 TRACE(" %s\n",debugstr_an((LPCSTR)pOptionalEntropy->pbData,pOptionalEntropy->cbData));
789 }
790
791}
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
const char * LPCSTR
Definition: xmlstorage.h:183

Referenced by CryptProtectData(), CryptUnprotectData(), extract_rev_infos(), extract_test(), get_subtests(), hex_str(), open_http(), print_version(), process_data(), remove_dir(), run_ex(), run_tests(), send_file(), strmake(), test_get_input_report(), test_read_device(), WinMain(), xmalloc(), xprintf(), xrealloc(), and xstrdup().

◆ serialize()

static BOOL serialize ( const struct protect_data_t pInfo,
DATA_BLOB pSerial 
)
static

Definition at line 217 of file protectdata.c.

218{
219 BYTE * ptr;
220 DWORD dwStrLen;
221 DWORD dwStruct;
222
223 TRACE("called\n");
224
225 if (!pInfo || !pInfo->szDataDescr || !pSerial ||
226 !pInfo->info0.pbData || !pInfo->info1.pbData ||
227 !pInfo->data0.pbData || !pInfo->salt.pbData ||
228 !pInfo->cipher.pbData || !pInfo->fingerprint.pbData)
229 {
230 return FALSE;
231 }
232
233 if (pInfo->info0.cbData!=16)
234 {
235 ERR("protect_data_t info0 not 16 bytes long\n");
236 }
237
238 if (pInfo->info1.cbData!=16)
239 {
240 ERR("protect_data_t info1 not 16 bytes long\n");
241 }
242
243 dwStrLen=lstrlenW(pInfo->szDataDescr);
244
245 pSerial->cbData=0;
246 pSerial->cbData+=sizeof(DWORD)*8; /* 8 raw DWORDs */
247 pSerial->cbData+=sizeof(DWORD)*4; /* 4 BLOBs with size */
248 pSerial->cbData+=pInfo->info0.cbData;
249 pSerial->cbData+=pInfo->info1.cbData;
250 pSerial->cbData+=(dwStrLen+1)*sizeof(WCHAR) + 4; /* str, null, size */
251 pSerial->cbData+=pInfo->data0.cbData;
252 pSerial->cbData+=pInfo->salt.cbData;
253 pSerial->cbData+=pInfo->cipher.cbData;
254 pSerial->cbData+=pInfo->fingerprint.cbData;
255
256 /* save the actual structure size */
257 dwStruct = pSerial->cbData;
258 /* There may be a 256 byte minimum, but I can't prove it. */
259 /*if (pSerial->cbData<256) pSerial->cbData=256;*/
260
261 pSerial->pbData=LocalAlloc(LPTR,pSerial->cbData);
262 if (!pSerial->pbData) return FALSE;
263
264 ptr=pSerial->pbData;
265
266 /* count0 */
267 serialize_dword(pInfo->count0,&ptr);
268 /*TRACE("used %u\n",ptr-pSerial->pbData);*/
269
270 /* info0 */
272 pInfo->info0.cbData,sizeof(BYTE),FALSE);
273 /*TRACE("used %u\n",ptr-pSerial->pbData);*/
274
275 /* count1 */
276 serialize_dword(pInfo->count1,&ptr);
277 /*TRACE("used %u\n",ptr-pSerial->pbData);*/
278
279 /* info1 */
281 pInfo->info1.cbData,sizeof(BYTE),FALSE);
282 /*TRACE("used %u\n",ptr-pSerial->pbData);*/
283
284 /* null0 */
285 serialize_dword(pInfo->null0,&ptr);
286 /*TRACE("used %u\n",ptr-pSerial->pbData);*/
287
288 /* szDataDescr */
290 (dwStrLen+1)*sizeof(WCHAR),sizeof(BYTE),TRUE);
291 /*TRACE("used %u\n",ptr-pSerial->pbData);*/
292
293 /* cipher_alg */
295 /*TRACE("used %u\n",ptr-pSerial->pbData);*/
296 /* cipher_key_len */
298 /*TRACE("used %u\n",ptr-pSerial->pbData);*/
299
300 /* data0 */
302 pInfo->data0.cbData,sizeof(BYTE),TRUE);
303 /*TRACE("used %u\n",ptr-pSerial->pbData);*/
304
305 /* null1 */
306 serialize_dword(pInfo->null1,&ptr);
307 /*TRACE("used %u\n",ptr-pSerial->pbData);*/
308
309 /* hash_alg */
311 /*TRACE("used %u\n",ptr-pSerial->pbData);*/
312 /* hash_len */
314 /*TRACE("used %u\n",ptr-pSerial->pbData);*/
315
316 /* salt */
318 pInfo->salt.cbData,sizeof(BYTE),TRUE);
319 /*TRACE("used %u\n",ptr-pSerial->pbData);*/
320
321 /* cipher */
323 pInfo->cipher.cbData,sizeof(BYTE),TRUE);
324 /*TRACE("used %u\n",ptr-pSerial->pbData);*/
325
326 /* fingerprint */
328 pInfo->fingerprint.cbData,sizeof(BYTE),TRUE);
329 /*TRACE("used %u\n",ptr-pSerial->pbData);*/
330
331 if (ptr - pSerial->pbData != dwStruct)
332 {
333 ERR("struct size changed!? expected %u\n", dwStruct);
334 LocalFree(pSerial->pbData);
335 pSerial->pbData=NULL;
336 pSerial->cbData=0;
337 return FALSE;
338 }
339
340 return TRUE;
341}
static void serialize_string(const BYTE *str, BYTE **ptr, DWORD len, DWORD width, BOOL prepend_len)
Definition: protectdata.c:151
static void serialize_dword(DWORD value, BYTE **ptr)
Definition: protectdata.c:142

Referenced by CryptProtectData().

◆ serialize_dword()

static void serialize_dword ( DWORD  value,
BYTE **  ptr 
)
static

Definition at line 142 of file protectdata.c.

143{
144 /*TRACE("called\n");*/
145
146 memcpy(*ptr,&value,sizeof(DWORD));
147 *ptr+=sizeof(DWORD);
148}
Definition: pdh_main.c:94

Referenced by serialize(), and serialize_string().

◆ serialize_string()

static void serialize_string ( const BYTE str,
BYTE **  ptr,
DWORD  len,
DWORD  width,
BOOL  prepend_len 
)
static

Definition at line 151 of file protectdata.c.

153{
154 /*TRACE("called %ux%u\n",(unsigned int)len,(unsigned int)width);*/
155
156 if (prepend_len)
157 {
159 }
161 *ptr+=len*width;
162}
GLint GLint GLsizei width
Definition: gl.h:1546
GLenum GLsizei len
Definition: glext.h:6722

Referenced by serialize().

◆ unserialize()

static BOOL unserialize ( const DATA_BLOB pSerial,
struct protect_data_t pInfo 
)
static

Definition at line 344 of file protectdata.c.

345{
346 BYTE * ptr;
347 DWORD index;
348 DWORD size;
350
351 TRACE("called\n");
352
353 if (!pInfo || !pSerial || !pSerial->pbData)
354 return FALSE;
355
356 index=0;
357 ptr=pSerial->pbData;
358 size=pSerial->cbData;
359
360 /* count0 */
361 if (!unserialize_dword(ptr,&index,size,&pInfo->count0))
362 {
363 ERR("reading count0 failed!\n");
364 return FALSE;
365 }
366
367 /* info0 */
368 if (!unserialize_string(ptr,&index,size,16,sizeof(BYTE),FALSE,
369 &pInfo->info0.pbData, &pInfo->info0.cbData))
370 {
371 ERR("reading info0 failed!\n");
372 return FALSE;
373 }
374
375 /* count1 */
376 if (!unserialize_dword(ptr,&index,size,&pInfo->count1))
377 {
378 ERR("reading count1 failed!\n");
379 return FALSE;
380 }
381
382 /* info1 */
383 if (!unserialize_string(ptr,&index,size,16,sizeof(BYTE),FALSE,
384 &pInfo->info1.pbData, &pInfo->info1.cbData))
385 {
386 ERR("reading info1 failed!\n");
387 return FALSE;
388 }
389
390 /* null0 */
391 if (!unserialize_dword(ptr,&index,size,&pInfo->null0))
392 {
393 ERR("reading null0 failed!\n");
394 return FALSE;
395 }
396
397 /* szDataDescr */
398 if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE,
399 (BYTE**)&pInfo->szDataDescr, NULL))
400 {
401 ERR("reading szDataDescr failed!\n");
402 return FALSE;
403 }
404
405 /* cipher_alg */
407 {
408 ERR("reading cipher_alg failed!\n");
409 return FALSE;
410 }
411
412 /* cipher_key_len */
414 {
415 ERR("reading cipher_key_len failed!\n");
416 return FALSE;
417 }
418
419 /* data0 */
420 if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE,
421 &pInfo->data0.pbData, &pInfo->data0.cbData))
422 {
423 ERR("reading data0 failed!\n");
424 return FALSE;
425 }
426
427 /* null1 */
428 if (!unserialize_dword(ptr,&index,size,&pInfo->null1))
429 {
430 ERR("reading null1 failed!\n");
431 return FALSE;
432 }
433
434 /* hash_alg */
435 if (!unserialize_dword(ptr,&index,size,&pInfo->hash_alg))
436 {
437 ERR("reading hash_alg failed!\n");
438 return FALSE;
439 }
440
441 /* hash_len */
442 if (!unserialize_dword(ptr,&index,size,&pInfo->hash_len))
443 {
444 ERR("reading hash_len failed!\n");
445 return FALSE;
446 }
447
448 /* salt */
449 if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE,
450 &pInfo->salt.pbData, &pInfo->salt.cbData))
451 {
452 ERR("reading salt failed!\n");
453 return FALSE;
454 }
455
456 /* cipher */
457 if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE,
458 &pInfo->cipher.pbData, &pInfo->cipher.cbData))
459 {
460 ERR("reading cipher failed!\n");
461 return FALSE;
462 }
463
464 /* fingerprint */
465 if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE,
466 &pInfo->fingerprint.pbData, &pInfo->fingerprint.cbData))
467 {
468 ERR("reading fingerprint failed!\n");
469 return FALSE;
470 }
471
472 /* allow structure size to be too big (since some applications
473 * will pad this up to 256 bytes, it seems) */
474 if (index>size)
475 {
476 /* this is an impossible-to-reach test, but if the padding
477 * issue is ever understood, this may become more useful */
478 ERR("loaded corrupt structure! (used %u expected %u)\n", index, size);
480 }
481
482 return status;
483}
#define index(s, c)
Definition: various.h:29
static BOOL unserialize_dword(const BYTE *ptr, DWORD *index, DWORD size, DWORD *value)
Definition: protectdata.c:165
static BOOL unserialize_string(const BYTE *ptr, DWORD *index, DWORD size, DWORD len, DWORD width, BOOL inline_len, BYTE **data, DWORD *stored)
Definition: protectdata.c:183
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031
Definition: ps.c:97

Referenced by CryptUnprotectData().

◆ unserialize_dword()

static BOOL unserialize_dword ( const BYTE ptr,
DWORD index,
DWORD  size,
DWORD value 
)
static

Definition at line 165 of file protectdata.c.

166{
167 /*TRACE("called\n");*/
168
169 if (!ptr || !index || !value) return FALSE;
170
171 if (*index+sizeof(DWORD)>size)
172 {
173 return FALSE;
174 }
175
176 memcpy(value,&(ptr[*index]),sizeof(DWORD));
177 *index+=sizeof(DWORD);
178
179 return TRUE;
180}

Referenced by unserialize(), and unserialize_string().

◆ unserialize_string()

static BOOL unserialize_string ( const BYTE ptr,
DWORD index,
DWORD  size,
DWORD  len,
DWORD  width,
BOOL  inline_len,
BYTE **  data,
DWORD stored 
)
static

Definition at line 183 of file protectdata.c.

186{
187 /*TRACE("called\n");*/
188
189 if (!ptr || !data) return FALSE;
190
191 if (inline_len) {
193 return FALSE;
194 }
195
196 if (*index+len*width>size)
197 {
198 return FALSE;
199 }
200
201 if (!(*data = CryptMemAlloc( len*width)))
202 {
203 return FALSE;
204 }
205
206 memcpy(*data,&(ptr[*index]),len*width);
207 if (stored)
208 {
209 *stored = len;
210 }
211 *index+=len*width;
212
213 return TRUE;
214}
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950

Referenced by unserialize().

◆ valid_protect_data()

static BOOL valid_protect_data ( const struct protect_data_t pInfo)
static

Definition at line 487 of file protectdata.c.

488{
490
491 TRACE("called\n");
492
493 if (pInfo->count0 != 0x0001)
494 {
495 ERR("count0 != 0x0001 !\n");
497 }
498 if (pInfo->count1 != 0x0001)
499 {
500 ERR("count0 != 0x0001 !\n");
502 }
503 if (pInfo->null0 != 0x0000)
504 {
505 ERR("null0 != 0x0000 !\n");
507 }
508 if (pInfo->null1 != 0x0000)
509 {
510 ERR("null1 != 0x0000 !\n");
512 }
513 /* since we have no idea what info0 is used for, and it seems
514 * rather constant, we can test for a Wine-specific magic string
515 * there to be reasonably sure we're using data created by the Wine
516 * implementation of CryptProtectData.
517 */
518 if (pInfo->info0.cbData!=strlen(crypt_magic_str)+1 ||
520 {
521 ERR("info0 magic value not matched !\n");
523 }
524
525 if (!status)
526 {
527 ERR("unrecognized CryptProtectData block\n");
528 }
529
530 return status;
531}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469

Referenced by CryptUnprotectData().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( crypt  )

Variable Documentation

◆ crypt32_protectdata_secret

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

Definition at line 56 of file protectdata.c.

Referenced by load_encryption_key().

◆ crypt_magic_str

const char crypt_magic_str[] = "Wine Crypt32 ok"
static

Definition at line 112 of file protectdata.c.

Referenced by fill_protect_data(), and valid_protect_data().