| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- #ifndef __kms_h
- #define __kms_h
- #ifndef CONFIG
- #define CONFIG "config.h"
- #endif // CONFIG
- #include CONFIG
- #if _MSC_VER
- #include <time.h>
- #else
- #include <sys/time.h>
- #endif // _MSC_VER
- #include <stdlib.h>
- #include "types.h"
- //
- // REQUEST... types are actually fixed size
- // RESPONSE... size may vary, defined here is max possible size
- //
- #define MAX_RESPONSE_SIZE 384
- #define PID_BUFFER_SIZE 64
- #define MAX_REQUEST_SIZE sizeof(REQUEST_V6)
- #define WORKSTATION_NAME_BUFFER 64
- // Constants for V6 time stamp interval
- #define TIME_C1 0x00000022816889BDULL
- #define TIME_C2 0x000000208CBAB5EDULL
- #define TIME_C3 0x3156CD5AC628477AULL
- #define VERSION_INFO union \
- { \
- DWORD Version;\
- struct { \
- WORD MinorVer; \
- WORD MajorVer; \
- } /*__packed*/; \
- } /*__packed*/
- // Aliases for various KMS struct members
- #define IsClientVM VMInfo
- #define GraceTime BindingExpiration
- #define MinutesRemaingInCurrentStatus BindingExpiration
- #define ID ActID
- #define ApplicationID AppID
- #define SkuId ActID
- #define KmsId KMSID
- #define ClientMachineId CMID
- #define MinimumClients N_Policy
- #define TimeStamp ClientTime
- #define PreviousCLientMachineId CMID_prev
- #define Salt IV
- #define XorSalt XoredIVs
- #define ActivationInterval VLActivationInterval
- #define RenewalInterval VLRenewalInterval
- typedef struct {
- VERSION_INFO;
- DWORD VMInfo; // 0 = client is bare metal / 1 = client is VM
- DWORD LicenseStatus; // 0 = Unlicensed, 1 = Licensed (Activated), 2 = OOB grace, 3 = OOT grace, 4 = NonGenuineGrace, 5 = Notification, 6 = extended grace
- DWORD BindingExpiration; // Expiration of the current status in minutes (e.g. when KMS activation or OOB grace expires).
- GUID AppID; // Can currently be Windows, Office2010 or Office2013 (see kms.c, table AppList).
- GUID ActID; // Most detailed product list. One product key per ActID (see kms.c, table ExtendedProductList). Is ignored by KMS server.
- GUID KMSID; // This is actually what the KMS server uses to grant or refuse activation (see kms.c, table BasicProductList).
- GUID CMID; // Client machine id. Used by the KMS server for counting minimum clients.
- DWORD N_Policy; // Minimum clients required for activation.
- FILETIME ClientTime; // Current client time.
- GUID CMID_prev; // previous client machine id. All zeros, if it never changed.
- WCHAR WorkstationName[64]; // Workstation name. FQDN if available, NetBIOS otherwise.
- } /*__packed*/ REQUEST;
- typedef struct {
- VERSION_INFO;
- DWORD PIDSize; // Size of PIDData in bytes.
- WCHAR KmsPID[PID_BUFFER_SIZE]; // ePID (must include terminating zero)
- GUID CMID; // Client machine id. Must be the same as in request.
- FILETIME ClientTime; // Current client time. Must be the same as in request.
- DWORD Count; // Current activated machines. KMS server counts up to N_Policy << 1 then stops
- DWORD VLActivationInterval; // Time in minutes when clients should retry activation if it was unsuccessful (default 2 hours)
- DWORD VLRenewalInterval; // Time in minutes when clients should renew KMS activation (default 7 days)
- } /*__packed*/ RESPONSE;
- #ifdef _DEBUG
- typedef struct {
- VERSION_INFO;
- DWORD PIDSize;
- WCHAR KmsPID[49]; // Set this to the ePID length you want to debug
- GUID CMID;
- FILETIME ClientTime;
- DWORD Count;
- DWORD VLActivationInterval;
- DWORD VLRenewalInterval;
- } __packed RESPONSE_DEBUG;
- #endif
- typedef struct {
- REQUEST RequestBase; // Base request
- BYTE MAC[16]; // Aes 160 bit CMAC
- } /*__packed*/ REQUEST_V4;
- typedef struct {
- RESPONSE ResponseBase; // Base response
- BYTE MAC[16]; // Aes 160 bit CMAC
- } /*__packed*/ RESPONSE_V4;
- typedef struct {
- VERSION_INFO; // unencrypted version info
- BYTE IV[16]; // IV
- REQUEST RequestBase; // Base Request
- BYTE Pad[4]; // since this struct is fixed, we use fixed PKCS pad bytes
- } /*__packed*/ REQUEST_V5;
- typedef REQUEST_V5 REQUEST_V6; // v5 and v6 requests are identical
- typedef struct {
- VERSION_INFO;
- BYTE IV[16];
- RESPONSE ResponseBase;
- BYTE RandomXoredIVs[16]; // If RequestIV was used for decryption: Random ^ decrypted Request IV ^ ResponseIV. If NULL IV was used for decryption: Random ^ decrypted Request IV
- BYTE Hash[32]; // SHA256 of Random used in RandomXoredIVs
- BYTE HwId[8]; // HwId from the KMS server
- BYTE XoredIVs[16]; // If RequestIV was used for decryption: decrypted Request IV ^ ResponseIV. If NULL IV was used for decryption: decrypted Request IV.
- BYTE HMAC[16]; // V6 Hmac (low 16 bytes only), see kms.c CreateV6Hmac
- //BYTE Pad[10]; // Pad is variable sized. So do not include in struct
- } /*__packed*/ RESPONSE_V6;
- typedef struct { // not used except for sizeof(). Fields are the same as RESPONSE_V6
- VERSION_INFO;
- BYTE IV[16];
- RESPONSE ResponseBase;
- BYTE RandomXoredIVs[16];
- BYTE Hash[32];
- } /*__packed*/ RESPONSE_V5;
- #ifdef _DEBUG
- typedef struct { // Debug structure for direct casting of RPC data in debugger
- VERSION_INFO;
- BYTE IV[16];
- RESPONSE_DEBUG ResponseBase;
- BYTE RandomXoredIVs[16];
- BYTE MAC[32];
- BYTE Unknown[8];
- BYTE XorSalts[16];
- BYTE HMAC[16];
- BYTE Pad[16];
- } __packed RESPONSE_V6_DEBUG;
- #endif
- #define V4_PRE_EPID_SIZE ( \
- sizeof(((RESPONSE*)0)->Version) + \
- sizeof(((RESPONSE*)0)->PIDSize) \
- )
- #define V4_POST_EPID_SIZE ( \
- sizeof(((RESPONSE*)0)->CMID) + \
- sizeof(((RESPONSE*)0)->ClientTime) + \
- sizeof(((RESPONSE*)0)->Count) + \
- sizeof(((RESPONSE*)0)->VLActivationInterval) + \
- sizeof(((RESPONSE*)0)->VLRenewalInterval) \
- )
- #define V6_DECRYPT_SIZE ( \
- sizeof(((REQUEST_V6*)0)->IV) + \
- sizeof(((REQUEST_V6*)0)->RequestBase) + \
- sizeof(((REQUEST_V6*)0)->Pad) \
- )
- #define V6_UNENCRYPTED_SIZE ( \
- sizeof(((RESPONSE_V6*)0)->Version) + \
- sizeof(((RESPONSE_V6*)0)->IV) \
- )
- #define V6_PRE_EPID_SIZE ( \
- V6_UNENCRYPTED_SIZE + \
- sizeof(((RESPONSE*)0)->Version) + \
- sizeof(((RESPONSE*)0)->PIDSize) \
- )
- #define V5_POST_EPID_SIZE ( \
- V4_POST_EPID_SIZE + \
- sizeof(((RESPONSE_V6*)0)->RandomXoredIVs) + \
- sizeof(((RESPONSE_V6*)0)->Hash) \
- )
- #define V6_POST_EPID_SIZE ( \
- V5_POST_EPID_SIZE + \
- sizeof(((RESPONSE_V6*)0)->HwId) + \
- sizeof(((RESPONSE_V6*)0)->XoredIVs) + \
- sizeof(((RESPONSE_V6*)0)->HMAC) \
- )
- #define RESPONSE_RESULT_OK ((1 << 10) - 1) //(9 bits)
- typedef union
- {
- DWORD mask;
- struct
- {
- BOOL HashOK : 1;
- BOOL TimeStampOK : 1;
- BOOL ClientMachineIDOK : 1;
- BOOL VersionOK : 1;
- BOOL IVsOK : 1;
- BOOL DecryptSuccess : 1;
- BOOL HmacSha256OK : 1;
- BOOL PidLengthOK : 1;
- BOOL RpcOK : 1;
- BOOL IVnotSuspicious : 1;
- BOOL reserved3 : 1;
- BOOL reserved4 : 1;
- BOOL reserved5 : 1;
- BOOL reserved6 : 1;
- uint32_t effectiveResponseSize : 9;
- uint32_t correctResponseSize : 9;
- };
- } RESPONSE_RESULT;
- typedef BYTE hwid_t[8];
- typedef struct
- {
- GUID guid;
- const char* name;
- const char* pid;
- uint8_t AppIndex;
- uint8_t KmsIndex;
- } KmsIdList;
- #define KMS_PARAM_MAJOR AppIndex
- #define KMS_PARAM_REQUIREDCOUNT KmsIndex
- #define APP_ID_WINDOWS 0
- #define APP_ID_OFFICE2010 1
- #define APP_ID_OFFICE2013 2
- #define EPID_INDEX_WINDOWS APP_ID_WINDOWS
- #define EPID_INDEX_OFFICE2010 APP_ID_OFFICE2010
- #define EPID_INDEX_OFFICE2013 APP_ID_OFFICE2013
- #define EPID_INDEX_OFFICE2016 3
- // Update these numbers in License Manager
- #define KMS_ID_OFFICE2010 0
- #define KMS_ID_OFFICE2013 1
- #define KMS_ID_OFFICE2013_BETA 2
- #define KMS_ID_OFFICE2016 3
- #define KMS_ID_VISTA 4
- #define KMS_ID_WIN7 5
- #define KMS_ID_WIN8_VL 6
- #define KMS_ID_WIN_BETA 7
- #define KMS_ID_WIN8_RETAIL 8
- #define KMS_ID_WIN81_VL 9
- #define KMS_ID_WIN81_RETAIL 10
- #define KMS_ID_WIN2008A 11
- #define KMS_ID_WIN2008B 12
- #define KMS_ID_WIN2008C 13
- #define KMS_ID_WIN2008R2A 14
- #define KMS_ID_WIN2008R2B 15
- #define KMS_ID_WIN2008R2C 16
- #define KMS_ID_WIN2012 17
- #define KMS_ID_WIN2012R2 18
- #define KMS_ID_WIN_SRV_BETA 19
- #define KMS_ID_WIN10_VL 20
- #define KMS_ID_WIN10_RETAIL 21
- #define KMS_ID_WIN2016 22
- #define KMS_ID_WIN10_LTSB2016 23
- #define PWINGUID &AppList[APP_ID_WINDOWS].guid
- #define POFFICE2010GUID &AppList[APP_ID_OFFICE2010].guid
- #define POFFICE2013GUID &AppList[APP_ID_OFFICE2013].guid
- typedef BOOL(__stdcall *RequestCallback_t)(const REQUEST *const baseRequest, RESPONSE *const baseResponse, BYTE *const hwId, const char* const ipstr);
- size_t CreateResponseV4(REQUEST_V4 *const Request, BYTE *const response_data, const char* const ipstr);
- size_t CreateResponseV6(REQUEST_V6 *restrict Request, BYTE *const response_data, const char* const ipstr);
- BYTE *CreateRequestV4(size_t *size, const REQUEST* requestBase);
- BYTE *CreateRequestV6(size_t *size, const REQUEST* requestBase);
- void randomPidInit();
- void get16RandomBytes(void* ptr);
- RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* Response_v6, int responseSize, BYTE* const response, const BYTE* const request, BYTE* hwid);
- RESPONSE_RESULT DecryptResponseV4(RESPONSE_V4* Response_v4, const int responseSize, BYTE* const response, const BYTE* const request);
- void getUnixTimeAsFileTime(FILETIME *const ts);
- __pure int64_t fileTimeToUnixTime(const FILETIME *const ts);
- const char* getProductNameHE(const GUID *const guid, const KmsIdList *const List, ProdListIndex_t *const i);
- const char* getProductNameLE(const GUID *const guid, const KmsIdList *const List, ProdListIndex_t *const i);
- __pure ProdListIndex_t getExtendedProductListSize();
- __pure ProdListIndex_t getAppListSize(void);
- extern const KmsIdList ProductList[];
- extern const KmsIdList AppList[];
- extern const KmsIdList ExtendedProductList[];
- extern RequestCallback_t CreateResponseBase;
- #ifdef _PEDANTIC
- uint16_t IsValidLcid(const uint16_t Lcid);
- #endif // _PEDANTIC
- #endif // __kms_h
|