Files
Domito/include/Domito.MinCrypt.h
T

635 lines
26 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* PROJECT: Veil
* FILE: Veil.h
* PURPOSE: Definition for the Windows Internal API from ntdll.dll,
* samlib.dll and winsta.dll
*
* LICENSE: Relicensed under The MIT License from The CC BY 4.0 License
*
* DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com)
*/
/*
* PROJECT: https://github.com/Ido-Moshe-Github/CiDllDemo
* FILE: ci.h
* PURPOSE: Definition for the ci.dll API and Struct.
*
* LICENSE: Relicensed under The MIT License from The CC BY 4.0 License
*
* DEVELOPER: [Ido Moshe, Liron Zuarets]
*
*/
#pragma once
// Warnings which disabled for compiling
#if _MSC_VER >= 1200
#pragma warning(push)
// nonstandard extension used : nameless struct/union
#pragma warning(disable:4201)
// 'struct_name' : structure was padded due to __declspec(align())
#pragma warning(disable:4324)
// 'enumeration': a forward declaration of an unscoped enumeration must have an
// underlying type (int assumed)
#pragma warning(disable:4471)
#endif
EXTERN_C_START
#ifndef _MINCRYPT_LIB
#define MINCRYPTAPI __declspec(dllimport)
#else
#define MINCRYPTAPI
#endif
//
// Algorithm IDs and Flags
//
// ALG_ID crackers
#define GET_ALG_CLASS(x) (x & (7 << 13))
#define GET_ALG_TYPE(x) (x & (15 << 9))
#define GET_ALG_SID(x) (x & (511))
// Algorithm classes
// certenrolld_begin -- ALG_CLASS_*
#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)
// certenrolld_end
// 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)
#if (NTDDI_VERSION >= NTDDI_VISTA)
#define ALG_TYPE_ECDH (7 << 9)
#endif //(NTDDI_VERSION >= NTDDI_VISTA)
#if (NTDDI_VERSION >= NTDDI_WIN10_RS1)
#define ALG_TYPE_THIRDPARTY (8 << 9)
#endif //(NTDDI_VERSION >= NTDDI_WIN10_RS1)
// Generic sub-ids
#define ALG_SID_ANY (0)
// Generic ThirdParty sub-ids
#if (NTDDI_VERSION >= NTDDI_WIN10_RS1)
#define ALG_SID_THIRDPARTY_ANY (0)
#endif //(NTDDI_VERSION >= NTDDI_WIN10_RS1)
// Some RSA sub-ids
#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
// Some DSS sub-ids
//
#define ALG_SID_DSS_ANY 0
#define ALG_SID_DSS_PKCS 1
#define ALG_SID_DSS_DMS 2
#if (NTDDI_VERSION >= NTDDI_VISTA)
#define ALG_SID_ECDSA 3
#endif //(NTDDI_VERSION >= NTDDI_VISTA)
// Block cipher sub ids
// DES sub_ids
#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
#if (NTDDI_VERSION >= NTDDI_WINXP)
#define ALG_SID_AES_128 14
#define ALG_SID_AES_192 15
#define ALG_SID_AES_256 16
#define ALG_SID_AES 17
#endif //(NTDDI_VERSION >= NTDDI_WINXP)
// Fortezza sub-ids
#define ALG_SID_SKIPJACK 10
#define ALG_SID_TEK 11
// KP_MODE
#define CRYPT_MODE_CBCI 6 // ANSI CBC Interleaved
#define CRYPT_MODE_CFBP 7 // ANSI CFB Pipelined
#define CRYPT_MODE_OFBP 8 // ANSI OFB Pipelined
#define CRYPT_MODE_CBCOFM 9 // ANSI CBC + OF Masking
#define CRYPT_MODE_CBCOFMI 10 // ANSI CBC + OFM Interleaved
// RC2 sub-ids
#define ALG_SID_RC2 2
// Stream cipher sub-ids
#define ALG_SID_RC4 1
#define ALG_SID_SEAL 2
// Diffie-Hellman sub-ids
#define ALG_SID_DH_SANDF 1
#define ALG_SID_DH_EPHEM 2
#define ALG_SID_AGREED_KEY_ANY 3
#define ALG_SID_KEA 4
#if (NTDDI_VERSION >= NTDDI_VISTA)
#define ALG_SID_ECDH 5
#define ALG_SID_ECDH_EPHEM 6
#endif //(NTDDI_VERSION >= NTDDI_VISTA)
// Hash sub ids
#define ALG_SID_MD2 1
#define ALG_SID_MD4 2
#define ALG_SID_MD5 3
#define ALG_SID_SHA 4
#define ALG_SID_SHA1 4
#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
#if (NTDDI_VERSION >= NTDDI_WINXP)
#define ALG_SID_HASH_REPLACE_OWF 11
#endif //(NTDDI_VERSION >= NTDDI_WINXP)
#if (NTDDI_VERSION > NTDDI_WINXPSP2)
#define ALG_SID_SHA_256 12
#define ALG_SID_SHA_384 13
#define ALG_SID_SHA_512 14
#endif //(NTDDI_VERSION > NTDDI_WINXPSP2)
// secure channel sub ids
#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
#if (NTDDI_VERSION >= NTDDI_VISTA)
// misc ECC sub ids
#define ALG_SID_ECMQV 1
#endif //(NTDDI_VERSION >= NTDDI_VISTA)
// Our silly example sub-id
#define ALG_SID_EXAMPLE 80
// certenrolls_begin -- PROV_ENUMALGS_EX
#ifndef ALGIDDEF
#define ALGIDDEF
typedef unsigned int ALG_ID;
#endif
// certenrolls_end
// algorithm identifier 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 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA1)
#define CALG_MAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MAC) // Deprecated. Don't use.
#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)
#if (NTDDI_VERSION >= NTDDI_WINXP)
#define CALG_NO_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_ANY | ALG_SID_ANY)
#endif //(NTDDI_VERSION >= NTDDI_WINXP)
#define CALG_RSA_KEYX (ALG_CLASS_KEY_EXCHANGE|ALG_TYPE_RSA|ALG_SID_RSA_ANY)
#define CALG_DES (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_DES)
#define CALG_3DES_112 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_3DES_112)
#define CALG_3DES (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_3DES)
#define CALG_DESX (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_DESX)
#define CALG_RC2 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_RC2)
#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_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_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) // Deprecated. Do not use
#define CALG_SSL3_SHAMD5 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SSL3SHAMD5)
#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)
#define CALG_RC5 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_RC5)
#define CALG_HMAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HMAC)
#define CALG_TLS1PRF (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_TLS1PRF)
#if (NTDDI_VERSION >= NTDDI_WINXP)
#define CALG_HASH_REPLACE_OWF (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HASH_REPLACE_OWF)
#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)
#endif //(NTDDI_VERSION >= NTDDI_WINXP)
#if (NTDDI_VERSION > NTDDI_WINXPSP2)
#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)
#endif //(NTDDI_VERSION > NTDDI_WINXPSP2)
#if (NTDDI_VERSION >= NTDDI_VISTA)
#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_ECMQV (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_ANY | ALG_SID_ECMQV)
#define CALG_ECDSA (ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_ECDSA)
#define CALG_NULLCIPHER (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_ANY | 0)
#endif //(NTDDI_VERSION >= NTDDI_VISTA)
#if (NTDDI_VERSION >= NTDDI_WIN10_RS1)
#define CALG_THIRDPARTY_KEY_EXCHANGE (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_THIRDPARTY | ALG_SID_THIRDPARTY_ANY)
#define CALG_THIRDPARTY_SIGNATURE (ALG_CLASS_SIGNATURE | ALG_TYPE_THIRDPARTY | ALG_SID_THIRDPARTY_ANY)
#define CALG_THIRDPARTY_CIPHER (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_THIRDPARTY | ALG_SID_THIRDPARTY_ANY)
#define CALG_THIRDPARTY_HASH (ALG_CLASS_HASH | ALG_TYPE_THIRDPARTY | ALG_SID_THIRDPARTY_ANY)
#endif //(NTDDI_VERSION >= NTDDI_WIN10_RS1)
#include <pshpack8.h>
typedef struct _MINCRYPTOAPI_BLOB
{
UINT32 Size;
_Field_size_bytes_(Size) UINT8* Data;
} MINCRYPT_INTEGER_BLOB, * PMINCRYPT_INTEGER_BLOB,
MINCRYPT_UINT_BLOB, * PMINCRYPT_UINT_BLOB,
MINCRYPT_OBJID_BLOB, * PMINCRYPT_OBJID_BLOB,
MINCERT_NAME_BLOB, * PMINCERT_NAME_BLOB,
MINCERT_RDN_VALUE_BLOB, * PMINCERT_RDN_VALUE_BLOB,
MINCERT_BLOB, * PMINCERT_BLOB,
MINCRL_BLOB, * PMINCRL_BLOB,
MINCRYPT_DATA_BLOB, * PMINCRYPT_DATA_BLOB,
MINCRYPT_HASH_BLOB, * PMINCRYPT_HASH_BLOB,
MINCRYPT_DIGEST_BLOB, * PMINCRYPT_DIGEST_BLOB,
MINCRYPT_DER_BLOB, * PMINCRYPT_DER_BLOB,
MINCRYPT_ATTR_BLOB, * PMINCRYPT_ATTR_BLOB;
// Encoded, length-delimited name bytes; not necessarily ANSI or NUL-terminated.
// The observed 26100 x64 string tag occupies padding; see the opt-in version header.
typedef struct _MINCRYPT_NAME_BLOB
{
_Field_size_bytes_(Size) PCHAR Data;
USHORT Size;
}MINCRYPT_NAME_BLOB, * PMINCRYPT_NAME_BLOB;
#define MINCRYPT_MAX_HASH_LENGTH (64)
#define MINCRYPT_SHA1_LENGTH (160/8)
#define MINCRYPT_SHA256_LENGTH (256/8)
#define MINCRYPT_SHA384_LENGTH (384/8)
#define MINCRYPT_SHA512_LENGTH (512/8)
typedef struct _MINCRYPT_CHAIN_ELEMENT
{
ALG_ID HashAlgId; // CALG_SHA1, CALG_SHA_256
UINT32 HashSize; // SHA1(160bit/8), SHA256(256bit/8)
UINT8 Hash[MINCRYPT_MAX_HASH_LENGTH];
MINCRYPT_NAME_BLOB Subject;
MINCRYPT_NAME_BLOB Issuer;
MINCERT_BLOB Certificate;
}MINCRYPT_CHAIN_ELEMENT, * PMINCRYPT_CHAIN_ELEMENT;
// CI owns one chain allocation; nested pointers borrow that allocation.
// Do not free child blobs separately or use memcpy to create a second owner.
typedef struct _MINCRYPT_CHAIN_INFO
{
UINT32 Size; // Observed 26100 x64: total allocation bytes, including trailing data.
MINCERT_BLOB* PublicKeys;
UINT32 NumberOfPublicKeys;
MINCERT_BLOB* EKUs;
UINT32 NumberOfEKUs;
#if (NTDDI_VERSION >= NTDDI_WIN10)
PMINCRYPT_CHAIN_ELEMENT ChainElements;
UINT32 NumberOfChainElement;
// REQUIRES a confirmed runtime layout (10586 and later sampled profiles).
// Sampled 10240 has only 56 header bytes: +0x38 begins variable payload.
// NTDDI_VERSION and allocation Size cannot establish field availability.
// See Domito.MinCrypt.Historical.h for distinct observed x64 prefix views.
MINCRYPT_ATTR_BLOB AuthenticodeAttributes;
// RootId occupies padding at +0x34 in all six historical x64 samples and
// 26100. The historical views name it without extending this default layout.
// 26100's 32-byte platform-manifest binary ID at +0x48 is named only in its
// explicit version header. Earlier 104-byte views reserve that extension.
// Do not infer field availability solely from NTDDI_VERSION or Size.
#endif // NTDDI_VERSION >= NTDDI_WIN10
/* memory layout */
// EKUs[NumberOfEKUs]
// PublicKeys[NumberOfPublicKeys]
// AuthenticodeAttributes.Data[AuthenticodeAttributes.Size]
// ChainElements[NumberOfChainElement]
}MINCRYPT_CHAIN_INFO, * PMINCRYPT_CHAIN_INFO;
typedef struct _MINCRYPT_POLICY_INFO
{
UINT32 Size;
NTSTATUS VerificationStatus; // Check API return status separately.
UINT32 PolicyBits;
MINCRYPT_CHAIN_INFO* ChainInfo;
LARGE_INTEGER RevocationTime; // When was the certificate revoked (if applicable)
#if (NTDDI_VERSION >= NTDDI_WIN10)
LARGE_INTEGER NotBefore; // Observed: signer certificate validity start.
LARGE_INTEGER NotAfter; // Observed: signer certificate validity end.
#endif // NTDDI_VERSION >= NTDDI_WIN10
}MINCRYPT_POLICY_INFO, *PMINCRYPT_POLICY_INFO;
#include <poppack.h>
/**
* Release a known initialized policy's owned ChainInfo allocation and reset it.
* Zero-initialize policy objects before first use. Release both signer and TSA
* policies after use, including failures, and before reusing output storage.
* Borrowed child pointers become invalid when the owner is released. Never clear
* Size while a chain is still owned. Size does not negotiate the runtime layout.
*
* @param PolicyInfo - initialized policy, not arbitrary uninitialized storage.
*
* Ignore the return value. The legacy PVOID declaration is retained for source
* compatibility; observed 26100 x64 code provides no defined pointer return.
*/
_IRQL_requires_max_(PASSIVE_LEVEL)
MINCRYPTAPI
PVOID
NTAPI
CiFreePolicyInfo(
_Inout_ MINCRYPT_POLICY_INFO* PolicyInfo
);
/**
* Digest-based workflow, also implemented on observed Windows 11 build 26100.
* Prefer the file-object workflow when its policy fits. Older-build ABI and
* KB3033929 requirements need a separately verified compatibility matrix.
*
* Given a file digest and signature of a file, verify the signature and provide information regarding
* the certificates that was used for signing (the entire certificate chain)
*
* @param Hash[in] - caller-computed file digest; CI does not recompute the file bytes
*
* @param HashSize - size of the digest, e.g. 0x14(160bit) for SHA1, 0x20(256bit) for SHA256
*
* @param HashAlgId - digest algorithm identifier, e.g. CALG_SHA1(0x8004), CALG_SHA_256(0x800C)
*
* @param SecurityDirectory - WIN_CERTIFICATE header, not the PKCS#7 payload.
* Observed 26100 x64 checks 4-byte pointer alignment, revision 0x200,
* type 2, supplied size >=12 and 8 < dwLength <= supplied size.
* This wrapper selects the first entry; it does not enumerate the table.
*
* @param SizeOfSecurityDirectory - size the security directory
*
* @param PolicyInfo[out] - PolicyInfo containing information about the signer certificate chain
*
* @param SigningTime[out] - when the file was signed (FILETIME format)
*
* @param TimeStampPolicyInfo[out] - PolicyInfo containing information about the timestamping authority (TSA) certificate chain
*
* @return Overall verification NTSTATUS. A successful policy VerificationStatus
* does not replace this return value: the final file-digest comparison
* can still fail. Both policy outputs may carry diagnostics on failure.
* See docs/mincrypt-contracts.md for ownership and policy limits.
* Various error values otherwise, for example:
* STATUS_INVALID_IMAGE_HASH - digest/signature or selected CI policy rejected
* STATUS_IMAGE_CERT_REVOKED - the certificate used for signing the file is revoked
* STATUS_IMAGE_CERT_EXPIRED - the certificate used for signing the file has expired
*/
_IRQL_requires_max_(PASSIVE_LEVEL)
MINCRYPTAPI
NTSTATUS
NTAPI
CiCheckSignedFile(
_In_reads_bytes_(HashSize) PVOID Hash,
_In_ UINT32 HashSize,
_In_ ALG_ID HashAlgId,
_In_reads_bytes_(SizeOfSecurityDirectory) PVOID SecurityDirectory,
_In_ UINT32 SizeOfSecurityDirectory,
_Out_ MINCRYPT_POLICY_INFO* PolicyInfo,
_Out_ LARGE_INTEGER* SigningTime,
_Out_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo
);
// Existing Domito compatibility filter, not a universal trusted-root policy.
// Includes test/DMD categories and a diagnostic bit; select policy deliberately.
#define DOMITO_CI_LEGACY_CATALOG_POLICY_BITS 0x0002007FUL
/**
* Digest-based workflow, also implemented on observed Windows 11 build 26100.
* Prefer the file-object workflow when its policy fits. Older-build ABI and
* KB3033929 requirements need a separately verified compatibility matrix.
*
* Finds a caller-computed file digest in an accepted installed catalog.
* Observed 26100 x64 file-hash lookup supports SHA-1 and SHA-256.
*
* @note must be attached to the PsInitialSystemProcess first!
*
* @param Hash[in] - caller-computed file digest; CI does not recompute the file bytes
*
* @param HashSize - size of the digest, e.g. 0x14(160bit) for SHA1, 0x20(256bit) for SHA256
*
* @param HashAlgId - digest algorithm identifier, e.g. CALG_SHA1(0x8004), CALG_SHA_256(0x800C)
*
* @param ReloadCatalogs - request catalog-store reload; process/silo and cache state matter.
*
* @param RequireTrustedCatalog - nonzero requires the observed catalog TRUSTED
* extension marker. This does not itself establish Microsoft signer trust.
*
* @param AcceptedCatalogPolicyBits - candidate catalog policy-bit filter.
* Observed 26100 x64 requires ANY overlap with catalog PolicyBits, not
* every requested bit. This is not a flags-to-enable input.
*
* @param PolicyInfo[out] - PolicyInfo containing information about the signer certificate chain.
*
* @param CatalogName[out option] - initialize empty; observed 26100 x64 returns
* a separate duplicated string allocation. Release a returned Buffer
* with RtlFreeUnicodeString, separately from both policy outputs.
*
* @param SigningTime[out] - when the file was signed (FILETIME format)
*
* @param TimeStampPolicyInfo[out] - PolicyInfo containing information about the timestamping authority (TSA) certificate chain.
*
* @return Overall verification NTSTATUS. A successful policy VerificationStatus
* does not replace this return value. Catalog selection and the
* selected policy still apply. Outputs may carry diagnostics on failure.
* See docs/mincrypt-contracts.md for ownership and policy limits.
* Various error values otherwise, for example:
* STATUS_INVALID_IMAGE_HASH - digest/signature or selected CI policy rejected
* STATUS_IMAGE_CERT_REVOKED - the certificate used for signing the file is revoked
* STATUS_IMAGE_CERT_EXPIRED - the certificate used for signing the file has expired
*/
_IRQL_requires_max_(PASSIVE_LEVEL)
MINCRYPTAPI
NTSTATUS
NTAPI
CiVerifyHashInCatalog(
_In_reads_bytes_(HashSize) PVOID Hash,
_In_ UINT32 HashSize,
_In_ ALG_ID HashAlgId,
_In_ BOOLEAN ReloadCatalogs,
_In_ UINT32 RequireTrustedCatalog,
_In_ UINT32 AcceptedCatalogPolicyBits,
_Out_ MINCRYPT_POLICY_INFO* PolicyInfo,
_Out_opt_ UNICODE_STRING* CatalogName,
_Out_ LARGE_INTEGER* SigningTime,
_Out_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo
);
#if (NTDDI_VERSION >= NTDDI_WIN10)
typedef
_IRQL_requires_same_
_Function_class_(MINCRYPT_ALLOCATE_ROUTINE)
__drv_allocatesMem(Mem)
PVOID
NTAPI
MINCRYPT_ALLOCATE_ROUTINE(
_In_ SIZE_T ByteSize
);
typedef MINCRYPT_ALLOCATE_ROUTINE* PMINCRYPT_ALLOCATE_ROUTINE;
/**
* Parse the publisher name from the certificate.
* Export absent from sampled Windows 10 x64 builds 10240–17134; observed present
* on 19041.1865, 22000.318 and 26100 x64; absent on sampled 19041.1 x64.
* The NTDDI guard does not establish runtime availability. See NOTES.md.
*
* @param Certificate - &PolicyInfo.ChainInfo->ChainElements[x].Certificate
*
* @param AllocateRoutine - used to allocate PublisherName buffer.
*
* @param PublisherName[out] - publisher name.
*
* @return NTSTATUS. The string byte count is returned in PublisherName->Length.
* Free PublisherName->Buffer with the allocator paired with AllocateRoutine,
* including on failure if a buffer was allocated. This routine extracts a name;
* it does not verify the certificate or its signer.
*/
MINCRYPTAPI
NTSTATUS
NTAPI
CiGetCertPublisherName(
_In_ MINCERT_BLOB* Certificate,
_In_ PMINCRYPT_ALLOCATE_ROUTINE AllocateRoutine,
_Out_ PUNICODE_STRING PublisherName
);
// Export observed already in 15063.0 x64 (1703); absent from sampled
// 10240/10586/14393 files. This writes CI-global state, not per-file policy.
MINCRYPTAPI
VOID
NTAPI
CiSetTrustedOriginClaimId(
_In_ UINT32 ClaimId
);
// Domito descriptive name, not an official Microsoft flag name.
// Observed on CI 10.0.26100.8328 x64: broadens the accepted-root mask in
// CipGetAcceptedRootKeys. Sampled 1709/1803 instead select 0x224FF; earlier helper
// generations differ. This is not a WinVerifyTrust-equivalent trust policy.
// See docs/ci-validate-file-object.md for evidence and version limitations.
#define DOMITO_CI_VALIDATE_FLAG_BROADEN_ROOT_ACCEPTANCE 0x00000020UL
// Descriptive experimental bit, not an official or isolated selector flag.
// Participates in first-success guards in examined 22621/26100 x64 CI bodies;
// also changes default-path policy and fallback. One 22631 TESTSIGNING-enabled
// BthPS3 run confirms 0x20|0x80 returns its primary company signer. It is not an
// arbitrary signer index, guaranteed primary selection, or a production default.
#define DOMITO_CI_VALIDATE_FLAG_FIRST_SUCCESS_EXPERIMENTAL 0x00000080UL
/**
* Given a file object, verify the signature and provide information regarding
* the certificates that was used for signing (the entire certificate chain)
*
* @param FileObject - FileObject of the PE in question
*
* @param ValidationFlags - validation policy flags; 0 is a valid value.
* See DOMITO_CI_VALIDATE_FLAG_BROADEN_ROOT_ACCEPTANCE and the accompanying documentation.
*
* @param RequestedSigningLevel - requested signing level; 0 is used by the probe.
* CI 26100 x64 consumes the low byte. UINT32 is retained for ABI compatibility
* until other supported architectures/builds are verified; use values in 0..255.
*
* @param PolicyInfo[out] - PolicyInfo containing information about the signer certificate chain.
*
* @param TimeStampPolicyInfo[out] - PolicyInfo containing information about the timestamping authority (TSA) certificate chain.
*
* @param SigningTime[out] - when the file was signed (FILETIME format)
*
* @param Hash[out] - file digest, not a certificate thumbprint. Supply at least
* MINCRYPT_MAX_HASH_LENGTH bytes (required by the observed 26100 x64 helper).
*
* @param HashSize[in,out] - buffer capacity on entry; actual digest size on success.
* Initialize to sizeof(Hash) for every call, including retries.
*
* @param HashAlgId - digest algorithm identifier, e.g. CALG_SHA1(0x8004), CALG_SHA_256(0x800C)
*
* Initialize both policy outputs to empty objects and free both with CiFreePolicyInfo
* before reuse. Do not interpret failed-call outputs as a verification result.
*
* @return STATUS_SUCCESS when verification succeeds under the selected CI policy.
* This does not by itself establish the application's signer trust policy.
* Various error values otherwise, for example:
* STATUS_INVALID_IMAGE_HASH - digest/signature or selected CI policy rejected
* STATUS_IMAGE_CERT_REVOKED - the certificate used for signing the file is revoked
* STATUS_IMAGE_CERT_EXPIRED - the certificate used for signing the file has expired
*/
_IRQL_requires_max_(PASSIVE_LEVEL)
MINCRYPTAPI
NTSTATUS
NTAPI
CiValidateFileObject(
_In_ FILE_OBJECT* FileObject,
_In_ UINT32 ValidationFlags,
_In_ UINT32 RequestedSigningLevel,
_Out_ MINCRYPT_POLICY_INFO* PolicyInfo,
_Out_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo,
_Out_ LARGE_INTEGER* SigningTime,
_Out_writes_bytes_(*HashSize) UINT8* Hash,
_Inout_ UINT32* HashSize,
_Out_ ALG_ID* HashAlgId
);
#endif // NTDDI_VERSION >= NTDDI_WIN10
EXTERN_C_END
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif