Added some crypto definitions + POC of dpapi with crypto.protect/unprotect

This commit is contained in:
clement rouault
2021-06-15 15:38:14 +02:00
parent 1d128f43ab
commit 408fe8aaa4
15 changed files with 8833 additions and 8033 deletions
@@ -0,0 +1,153 @@
#define ALG_CLASS_ANY (0)
#define ALG_CLASS_SIGNATURE (1 << 13)
#define ALG_CLASS_MSG_ENCRYPT (2 << 13)
#define ALG_CLASS_DATA_ENCRYPT (3 << 13)
#define ALG_CLASS_HASH (4 << 13)
#define ALG_CLASS_KEY_EXCHANGE (5 << 13)
#define ALG_CLASS_ALL (7 << 13)
/* Algorithm types */
#define ALG_TYPE_ANY (0)
#define ALG_TYPE_DSS (1 << 9)
#define ALG_TYPE_RSA (2 << 9)
#define ALG_TYPE_BLOCK (3 << 9)
#define ALG_TYPE_STREAM (4 << 9)
#define ALG_TYPE_DH (5 << 9)
#define ALG_TYPE_SECURECHANNEL (6 << 9)
#define ALG_TYPE_ECDH (7 << 9)
/* SIDs */
#define ALG_SID_ANY (0)
/* RSA SIDs */
#define ALG_SID_RSA_ANY 0
#define ALG_SID_RSA_PKCS 1
#define ALG_SID_RSA_MSATWORK 2
#define ALG_SID_RSA_ENTRUST 3
#define ALG_SID_RSA_PGP 4
/* DSS SIDs */
#define ALG_SID_DSS_ANY 0
#define ALG_SID_DSS_PKCS 1
#define ALG_SID_DSS_DMS 2
#define ALG_SID_ECDSA 3
/* DES SIDs */
#define ALG_SID_DES 1
#define ALG_SID_3DES 3
#define ALG_SID_DESX 4
#define ALG_SID_IDEA 5
#define ALG_SID_CAST 6
#define ALG_SID_SAFERSK64 7
#define ALG_SID_SAFERSK128 8
#define ALG_SID_3DES_112 9
#define ALG_SID_CYLINK_MEK 12
#define ALG_SID_RC5 13
#define ALG_SID_AES_128 14
#define ALG_SID_AES_192 15
#define ALG_SID_AES_256 16
#define ALG_SID_AES 17
/* Fortezza */
#define ALG_SID_SKIPJACK 10
#define ALG_SID_TEK 11
/* Diffie-Hellmans SIDs */
#define ALG_SID_DH_SANDF 1
#define ALG_SID_DH_EPHEM 2
#define ALG_SID_AGREED_KEY_ANY 3
#define ALG_SID_KEA 4
#define ALG_SID_ECDH 5
#define ALG_SID_ECDH_EPHEM 6
/* RC2 SIDs */
#define ALG_SID_RC4 1
#define ALG_SID_RC2 2
#define ALG_SID_SEAL 2
/* Hash SIDs */
#define ALG_SID_MD2 1
#define ALG_SID_MD4 2
#define ALG_SID_MD5 3
#define ALG_SID_SHA 4
#define ALG_SID_SHA1 ALG_SID_SHA
#define ALG_SID_MAC 5
#define ALG_SID_RIPEMD 6
#define ALG_SID_RIPEMD160 7
#define ALG_SID_SSL3SHAMD5 8
#define ALG_SID_HMAC 9
#define ALG_SID_TLS1PRF 10
#define ALG_SID_HASH_REPLACE_OWF 11
#define ALG_SID_SHA_256 12
#define ALG_SID_SHA_384 13
#define ALG_SID_SHA_512 14
/* SCHANNEL SIDs */
#define ALG_SID_SSL3_MASTER 1
#define ALG_SID_SCHANNEL_MASTER_HASH 2
#define ALG_SID_SCHANNEL_MAC_KEY 3
#define ALG_SID_PCT1_MASTER 4
#define ALG_SID_SSL2_MASTER 5
#define ALG_SID_TLS1_MASTER 6
#define ALG_SID_SCHANNEL_ENC_KEY 7
#define ALG_SID_EXAMPLE 80
#define ALG_SID_ECMQV 1
/* Algorithm Definitions */
#define CALG_MD2 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD2)
#define CALG_MD4 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD4)
#define CALG_MD5 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD5)
#define CALG_SHA (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA)
#define CALG_SHA1 CALG_SHA
#define CALG_MAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MAC)
#define CALG_SSL3_SHAMD5 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SSL3SHAMD5)
#define CALG_HMAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HMAC)
#define CALG_TLS1PRF (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_TLS1PRF)
#define CALG_HASH_REPLACE_OWF (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HASH_REPLACE_OWF)
#define CALG_SHA_256 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_256)
#define CALG_SHA_384 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_384)
#define CALG_SHA_512 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_512)
#define CALG_RSA_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_RSA | ALG_SID_RSA_ANY)
#define CALG_DSS_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_DSS_ANY)
#define CALG_NO_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_ANY | ALG_SID_ANY)
#define CALG_ECDSA (ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_ECDSA)
#define CALG_DH_SF (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_DH_SANDF)
#define CALG_DH_EPHEM (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_DH_EPHEM)
#define CALG_AGREEDKEY_ANY (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_AGREED_KEY_ANY)
#define CALG_KEA_KEYX (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_KEA)
#define CALG_HUGHES_MD5 (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_ANY | ALG_SID_MD5)
#define CALG_ECDH (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_ECDH)
#define CALG_ECDH_EPHEM (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_ECDH | ALG_SID_ECDH_EPHEM)
#define CALG_RSA_KEYX (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_RSA | ALG_SID_RSA_ANY)
#define CALG_ECMQV (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_ANY | ALG_SID_ECMQV)
#define CALG_DES (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_DES)
#define CALG_RC2 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_RC2)
#define CALG_3DES (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_3DES)
#define CALG_3DES_112 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_3DES_112)
#define CALG_DESX (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_DESX)
#define CALG_AES_128 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_128)
#define CALG_AES_192 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_192)
#define CALG_AES_256 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_256)
#define CALG_AES (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES)
#define CALG_RC4 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_RC4)
#define CALG_SEAL (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_SEAL)
#define CALG_RC5 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_RC5)
#define CALG_SKIPJACK (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_SKIPJACK)
#define CALG_TEK (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_TEK)
#define CALG_CYLINK_MEK (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_CYLINK_MEK)
#define CALG_SSL3_MASTER (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SSL3_MASTER)
#define CALG_SCHANNEL_MASTER_HASH (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SCHANNEL_MASTER_HASH)
#define CALG_SCHANNEL_MAC_KEY (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SCHANNEL_MAC_KEY)
#define CALG_SCHANNEL_ENC_KEY (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SCHANNEL_ENC_KEY)
#define CALG_PCT1_MASTER (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_PCT1_MASTER)
#define CALG_SSL2_MASTER (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SSL2_MASTER)
#define CALG_TLS1_MASTER (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_TLS1_MASTER)
/* Protocol Flags */
#define CRYPT_FLAG_PCT1 0x0001
#define CRYPT_FLAG_SSL2 0x0002
#define CRYPT_FLAG_SSL3 0x0004
#define CRYPT_FLAG_TLS1 0x0008
#define CRYPT_FLAG_IPSEC 0x0010
#define CRYPT_FLAG_SIGNING 0x0020
#define HP_ALGID 0x0001 // Hash algorithm
#define HP_HASHVAL 0x0002 // Hash value
#define HP_HASHSIZE 0x0004 // Hash value size
#define HP_HMAC_INFO 0x0005 // information for creating an HMAC
#define HP_TLS1PRF_LABEL 0x0006 // label for TLS1 PRF
#define HP_TLS1PRF_SEED 0x0007 // seed for TLS1 PRF
@@ -0,0 +1,94 @@
//
// CryptProtect PromptStruct dwPromtFlags
//
//
// prompt on unprotect
#define CRYPTPROTECT_PROMPT_ON_UNPROTECT 0x1 // 1<<0
//
// prompt on protect
#define CRYPTPROTECT_PROMPT_ON_PROTECT 0x2 // 1<<1
#define CRYPTPROTECT_PROMPT_RESERVED 0x04 // reserved, do not use.
//
// default to strong variant UI protection (user supplied password currently).
#define CRYPTPROTECT_PROMPT_STRONG 0x08 // 1<<3
//
// require strong variant UI protection (user supplied password currently).
#define CRYPTPROTECT_PROMPT_REQUIRE_STRONG 0x10 // 1<<4
//
// CryptProtectData and CryptUnprotectData dwFlags
//
// for remote-access situations where ui is not an option
// if UI was specified on protect or unprotect operation, the call
// will fail and GetLastError() will indicate ERROR_PASSWORD_RESTRICTION
#define CRYPTPROTECT_UI_FORBIDDEN 0x1
//
// per machine protected data -- any user on machine where CryptProtectData
// took place may CryptUnprotectData
#define CRYPTPROTECT_LOCAL_MACHINE 0x4
//
// force credential synchronize during CryptProtectData()
// Synchronize is only operation that occurs during this operation
#define CRYPTPROTECT_CRED_SYNC 0x8
//
// Generate an Audit on protect and unprotect operations
//
#define CRYPTPROTECT_AUDIT 0x10
//
// Protect data with a non-recoverable key
//
#define CRYPTPROTECT_NO_RECOVERY 0x20
//
// Verify the protection of a protected blob
//
#define CRYPTPROTECT_VERIFY_PROTECTION 0x40
//
// Regenerate the local machine protection
//
#define CRYPTPROTECT_CRED_REGENERATE 0x80
// flags reserved for system use
#define CRYPTPROTECT_FIRST_RESERVED_FLAGVAL 0x0FFFFFFF
#define CRYPTPROTECT_LAST_RESERVED_FLAGVAL 0xFFFFFFFF
//
// The buffer length passed into CryptProtectMemory and CryptUnprotectMemory
// must be a multiple of this length (or zero).
//
#define CRYPTPROTECTMEMORY_BLOCK_SIZE 16
//
// CryptProtectMemory/CryptUnprotectMemory dwFlags
//
//
// Encrypt/Decrypt within current process context.
//
#define CRYPTPROTECTMEMORY_SAME_PROCESS 0x00
//
// Encrypt/Decrypt across process boundaries.
// eg: encrypted buffer passed across LPC to another process which calls CryptUnprotectMemory.
//
#define CRYPTPROTECTMEMORY_CROSS_PROCESS 0x01
//
// Encrypt/Decrypt across callers with same LogonId.
// eg: encrypted buffer passed across LPC to another process which calls CryptUnprotectMemory whilst impersonating.
//
#define CRYPTPROTECTMEMORY_SAME_LOGON 0x02
@@ -258,6 +258,98 @@ BOOL WINAPI CryptReleaseContext(
_In_ DWORD dwFlags
);
BOOL CryptCreateHash(
HCRYPTPROV hProv,
ALG_ID Algid,
HCRYPTKEY hKey,
DWORD dwFlags,
HCRYPTHASH *phHash
);
BOOL CryptHashData(
HCRYPTHASH hHash,
BYTE *pbData,
DWORD dwDataLen,
DWORD dwFlags
);
BOOL CryptGetHashParam(
HCRYPTHASH hHash,
DWORD dwParam,
BYTE *pbData,
DWORD *pdwDataLen,
DWORD dwFlags
);
BOOL CryptVerifySignatureA(
HCRYPTHASH hHash,
BYTE *pbSignature,
DWORD dwSigLen,
HCRYPTKEY hPubKey,
LPCSTR szDescription,
DWORD dwFlags
);
BOOL CryptVerifySignatureW(
HCRYPTHASH hHash,
BYTE *pbSignature,
DWORD dwSigLen,
HCRYPTKEY hPubKey,
LPCWSTR szDescription,
DWORD dwFlags
);
BOOL CryptSignHashA(
HCRYPTHASH hHash,
DWORD dwKeySpec,
LPCSTR szDescription,
DWORD dwFlags,
BYTE *pbSignature,
DWORD *pdwSigLen
);
BOOL CryptSignHashW(
HCRYPTHASH hHash,
DWORD dwKeySpec,
LPCWSTR szDescription,
DWORD dwFlags,
BYTE *pbSignature,
DWORD *pdwSigLen
);
BOOL CryptDestroyHash(
HCRYPTHASH hHash
);
BOOL CryptEncrypt(
HCRYPTKEY hKey,
HCRYPTHASH hHash,
BOOL Final,
DWORD dwFlags,
BYTE *pbData,
DWORD *pdwDataLen,
DWORD dwBufLen
);
BOOL CryptDecrypt(
HCRYPTKEY hKey,
HCRYPTHASH hHash,
BOOL Final,
DWORD dwFlags,
BYTE *pbData,
DWORD *pdwDataLen
);
BOOL CryptDeriveKey(
HCRYPTPROV hProv,
ALG_ID Algid,
HCRYPTHASH hBaseData,
DWORD dwFlags,
HCRYPTKEY *phKey
);
BOOL WINAPI CryptExportKey(
_In_ HCRYPTKEY hKey,
_In_ HCRYPTKEY hExpKey,
@@ -267,6 +359,14 @@ BOOL WINAPI CryptExportKey(
_Inout_ DWORD *pdwDataLen
);
BOOL CryptImportKey(
HCRYPTPROV hProv,
BYTE *pbData,
DWORD dwDataLen,
HCRYPTKEY hPubKey,
DWORD dwFlags,
HCRYPTKEY *phKey
);
BOOL WINAPI CertGetCertificateContextProperty(
_In_ PCCERT_CONTEXT pCertContext,
@@ -0,0 +1,31 @@
BOOL CryptProtectData(
DATA_BLOB *pDataIn,
LPCWSTR szDataDescr,
DATA_BLOB *pOptionalEntropy,
PVOID pvReserved,
CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct,
DWORD dwFlags,
DATA_BLOB *pDataOut
);
BOOL CryptUnprotectData(
DATA_BLOB *pDataIn,
LPWSTR *ppszDataDescr,
DATA_BLOB *pOptionalEntropy,
PVOID pvReserved,
CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct,
DWORD dwFlags,
DATA_BLOB *pDataOut
);
BOOL CryptProtectMemory(
LPVOID pDataIn,
DWORD cbDataIn,
DWORD dwFlags
);
BOOL CryptUnprotectMemory(
LPVOID pDataIn,
DWORD cbDataIn,
DWORD dwFlags
);
@@ -711,4 +711,23 @@ typedef struct _SPC_INDIRECT_DATA_CONTENT
CRYPT_ALGORITHM_IDENTIFIER DigestAlgorithm;
CRYPT_HASH_BLOB Digest;
} SPC_INDIRECT_DATA_CONTENT, *PSPC_INDIRECT_DATA_CONTENT;
} SPC_INDIRECT_DATA_CONTENT, *PSPC_INDIRECT_DATA_CONTENT;
typedef struct _PUBLICKEYSTRUC {
BYTE bType;
BYTE bVersion;
WORD reserved;
ALG_ID aiKeyAlg;
} BLOBHEADER, PUBLICKEYSTRUC;
// The structure is described at https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/jj650836(v=vs.85)
// But PLAINTEXTKEYBLOB is a define '#define PLAINTEXTKEYBLOB 0x8' in WinCrypt.h
// So I guess this struct is reaaly defined no-where
// So the sample for importing a plain key
// https://docs.microsoft.com/en-us/windows/win32/seccrypto/example-c-program--importing-a-plaintext-key
// The BLOB is in a BYTE DesKeyBlob[] & not a real struct :')
typedef struct _STRUCT_PLAINTEXTKEYBLOB {
BLOBHEADER hdr;
DWORD dwKeySize;
BYTE rgbKeyData[0];
} STRUCT_PLAINTEXTKEYBLOB, *PSTRUCT_PLAINTEXTKEYBLOB;
@@ -0,0 +1,6 @@
typedef struct _CRYPTPROTECT_PROMPTSTRUCT {
DWORD cbSize;
DWORD dwPromptFlags;
HWND hwndApp;
LPCWSTR szPrompt;
} CRYPTPROTECT_PROMPTSTRUCT, *PCRYPTPROTECT_PROMPTSTRUCT;