You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
3.8 KiB
151 lines
3.8 KiB
/*++
|
|
|
|
Copyright (C) Microsoft Corporation, 2002 - 2002
|
|
|
|
Module Name:
|
|
|
|
encraption.h
|
|
|
|
Abstract:
|
|
|
|
This module contains simple obfuscation algorithm to hide communication
|
|
keys.
|
|
|
|
Author:
|
|
Carsten Hansen
|
|
Alper Selcuk
|
|
|
|
|
|
--*/
|
|
|
|
|
|
#ifndef _ENCRAPTION_H
|
|
#define _ENCRAPTION_H
|
|
|
|
//=============================================================================
|
|
//
|
|
// This routine clears the given key. The encryption/decryption method is
|
|
// developed by CarstenH.
|
|
//
|
|
NTSTATUS __forceinline ClearKey(
|
|
const BYTE *PrivKey,
|
|
BYTE *ClearKey,
|
|
ULONG KeySize,
|
|
ULONG MagicNumber2)
|
|
{
|
|
const char * pszName = "Microsoft Corporation";
|
|
|
|
/* Convert the obfuscated key to clear */
|
|
BYTE *clearDRMKPriv;
|
|
|
|
clearDRMKPriv = (BYTE *) ExAllocatePool(PagedPool, KeySize);
|
|
if (NULL == clearDRMKPriv) {
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
/* Permute bytes */
|
|
int k = 1;
|
|
clearDRMKPriv[0] = PrivKey[0];
|
|
do {
|
|
int l = k * MagicNumber2 % (KeySize - 1);
|
|
clearDRMKPriv[k] = PrivKey[l];
|
|
if (l == 1)
|
|
break;
|
|
k = l;
|
|
} while (1);
|
|
clearDRMKPriv[KeySize - 1] = PrivKey[KeySize - 1];
|
|
|
|
/* Swap nibbles */
|
|
DWORD * pdw = (DWORD *) clearDRMKPriv;
|
|
DWORD * qdw = (DWORD *) (clearDRMKPriv + KeySize);
|
|
DWORD granularity = 4;
|
|
for (; pdw < qdw; ++ pdw)
|
|
{
|
|
DWORD temp = 0xF0F0F0F0;
|
|
temp &= *pdw;
|
|
*pdw ^= temp;
|
|
temp ^= (*pdw << granularity);
|
|
*pdw |= (*pdw << granularity);
|
|
*pdw ^= (temp >> granularity);
|
|
}
|
|
|
|
/* XOR with "Microsoft" */
|
|
ULONG len = strlen(pszName);
|
|
for (ULONG i = 0, j = 0; i < KeySize; ++i)
|
|
{
|
|
clearDRMKPriv[i] ^= pszName[j];
|
|
++j;
|
|
if (j > len)
|
|
j = 0;
|
|
}
|
|
|
|
RtlCopyMemory(ClearKey, clearDRMKPriv, KeySize);
|
|
|
|
RtlZeroMemory(clearDRMKPriv, KeySize);
|
|
ExFreePool(clearDRMKPriv);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
/* Obfuscation algorithm.
|
|
{
|
|
// XOR with "Microsoft"
|
|
int len = strlen(pszName);
|
|
for (int i = 0, j = 0; i < sizeof(objDRMKPriv); ++i)
|
|
{
|
|
objDRMKPriv[i] = DRMKpriv[i] ^ pszName[j];
|
|
++j;
|
|
if (j > len)
|
|
j = 0;
|
|
}
|
|
|
|
// Swap nibbles
|
|
DWORD * pdw = (DWORD *) objDRMKPriv;
|
|
DWORD * qdw = (DWORD *) (objDRMKPriv + sizeof(objDRMKPriv));
|
|
DWORD granularity = 4;
|
|
for (; pdw < qdw; ++ pdw)
|
|
{
|
|
DWORD temp = 0xF0F0F0F0;
|
|
temp &= *pdw;
|
|
*pdw ^= temp;
|
|
temp ^= (*pdw << granularity);
|
|
*pdw |= (*pdw << granularity);
|
|
*pdw ^= (temp >> granularity);
|
|
}
|
|
|
|
// Permute bytes
|
|
int k = 1;
|
|
BYTE temp = objDRMKPriv[k];
|
|
do {
|
|
int l = k * MAGIC_NUMBER_1 % (sizeof(objDRMKPriv) - 1);
|
|
if (l == 1)
|
|
break;
|
|
objDRMKPriv[k] = objDRMKPriv[l];
|
|
k = l;
|
|
} while (1);
|
|
objDRMKPriv[k] = temp;
|
|
}
|
|
*/
|
|
|
|
/* Clean Key and Cert
|
|
static const BYTE DRMKpriv[20] = {
|
|
0x80, 0x0B, 0x97, 0x30, 0x7A, 0xFB, 0x1B, 0x3B,
|
|
0xB7, 0xB2, 0x0F, 0x44, 0x63, 0xD8, 0xA5, 0x2D,
|
|
0xD5, 0xBC, 0x3D, 0x75};
|
|
static const BYTE DRMKCert[104] = {
|
|
0x00, 0x01, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
|
|
0x46, 0xB1, 0x18, 0x76, 0x66, 0xBE, 0x91, 0xEC,
|
|
0xBD, 0x06, 0x50, 0x72, 0x1B, 0x8C, 0xD3, 0x55,
|
|
0xD2, 0x1A, 0xB7, 0x60, 0x6C, 0x65, 0xDD, 0xE4,
|
|
0x54, 0xCE, 0xFD, 0xEB, 0x4A, 0x9F, 0x0A, 0x5A,
|
|
0xD1, 0x44, 0xB2, 0x32, 0xB9, 0xA0, 0x84, 0x67,
|
|
0x55, 0xD7, 0xFE, 0x45, 0xD5, 0x16, 0x36, 0x7B,
|
|
0xEC, 0x3C, 0xFF, 0x7D, 0x4C, 0x09, 0x9A, 0x7B,
|
|
0xB4, 0x6C, 0xEF, 0x2B, 0xC5, 0xF8, 0xA3, 0xC4,
|
|
0xE2, 0x57, 0xC5, 0x87, 0xA6, 0x75, 0x85, 0xFE,
|
|
0xE2, 0x34, 0xA3, 0x30, 0xAE, 0x4D, 0xDB, 0x23,
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x06,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
|
|
*/
|
|
|
|
#endif
|