windows-nt/Source/XPSP1/NT/net/config/netcfg/wlbscfg/license.c
2020-09-26 16:20:57 +08:00

232 lines
5.9 KiB
C

/*++
Copyright(c) 2000 Microsoft Corporation
Module Name:
license.cpp
Abstract:
Windows Load Balancing Service (WLBS)
Code to encrypt/decrypt passwords and port rules.
Author:
kyrilf
History:
JosephJ 11/22/00 Gutted this file and folded in three constants from
the now defunct license.h. Basically the functions in this
file used to do lots of things but now only encrypt/decrypt
port rules and passwords. The port rules stuff is only used
for upgrading from olde versions of wlbs so that may go away
as well.
This file is located in two places:
WLBS netconfig code -- net\config\netcfg\wlbscfg
WLBS API code -- net\wlbs\api
Because this involves password encryption, we don't want to make
the functions callable via a DLL entrypoint, and setting up
a static library to be shared between netconfig and api stuff is
not trivial and overkill because the two trees are far apart.
--*/
// #include <precomp.h>
#include <windows.h>
#include "wlbsparm.h"
#include "license.h"
/* CONSTANTS */
static UCHAR data_key [] =
{ 0x3f, 0xba, 0x6e, 0xf0, 0xe1, 0x44, 0x1b, 0x45,
0x41, 0xc4, 0x9f, 0xfb, 0x46, 0x54, 0xbc, 0x43 };
static UCHAR str_key [] =
{ 0xdb, 0x1b, 0xac, 0x1a, 0xb9, 0xb1, 0x18, 0x03,
0x55, 0x57, 0x4a, 0x62, 0x36, 0x21, 0x7c, 0xa6 };
/* Encryption and decryption routines are based on a public-domain Tiny
Encryption Algorithm (TEA) by David Wheeler and Roger Needham at the
Computer Laboratory of Cambridge University. For reference, please
consult http://vader.brad.ac.uk/tea/tea.shtml */
static VOID License_decipher (
PULONG v,
PULONG k)
{
ULONG y = v [0],
z = v [1],
a = k [0],
b = k [1],
c = k [2],
d = k [3],
n = 32,
sum = 0xC6EF3720,
delta = 0x9E3779B9;
/* sum = delta<<5, in general sum = delta * n */
while (n-- > 0)
{
z -= (y << 4) + c ^ y + sum ^ (y >> 5) + d;
y -= (z << 4) + a ^ z + sum ^ (z >> 5) + b;
sum -= delta;
}
v [0] = y; v [1] = z;
} /* end License_decipher */
static VOID License_encipher (
PULONG v,
PULONG k)
{
ULONG y = v [0],
z = v [1],
a = k [0],
b = k [1],
c = k [2],
d = k [3],
n = 32,
sum = 0,
delta = 0x9E3779B9;
while (n-- > 0)
{
sum += delta;
y += (z << 4) + a ^ z + sum ^ (z >> 5) + b;
z += (y << 4) + c ^ y + sum ^ (y >> 5) + d;
}
v [0] = y; v [1] = z;
} /* end License_encipher */
BOOL License_data_decode (
PCHAR data,
ULONG len)
{
ULONG i;
if (len % LICENSE_DATA_GRANULARITY != 0)
return FALSE;
for (i = 0; i < len; i += LICENSE_DATA_GRANULARITY)
License_decipher ((PULONG) (data + i), (PULONG) data_key);
return TRUE;
} /* License_data_decode */
ULONG License_string_encode (
PCHAR str)
{
CHAR buf [LICENSE_STR_IMPORTANT_CHARS + 1];
ULONG code, i;
PULONG nibp;
for (i = 0; i < LICENSE_STR_IMPORTANT_CHARS; i++)
{
if (str[i] == 0)
break;
buf[i] = str[i];
}
for (; i < LICENSE_STR_IMPORTANT_CHARS + 1; i ++)
buf[i] = 0;
for (i = 0; i < LICENSE_STR_NIBBLES; i ++)
License_encipher ((PULONG) (buf + i * LICENSE_DATA_GRANULARITY),
(PULONG) str_key);
for (i = 0, code = 0; i < LICENSE_STR_NIBBLES; i ++)
{
nibp = (PULONG) (buf + (i * LICENSE_DATA_GRANULARITY));
code ^= nibp [0] ^ nibp [1];
}
/* V2.2 - if password consists of the same characters - XORing nibbles
above makes it go to 0 - put some recovery for that special case since
we cannot modify the algorithm due to legacy issues */
if (code == 0 && str [0] != 0)
code = * ((PULONG) buf);
return code;
} /* License_string_encode */
ULONG License_wstring_encode (
PWCHAR str)
{
CHAR buf [LICENSE_STR_IMPORTANT_CHARS + 1];
ULONG code, i;
PULONG nibp;
for (i = 0; i < LICENSE_STR_IMPORTANT_CHARS; i++)
{
if (str[i] == 0)
break;
buf[i] = (UCHAR)str[i];
}
for (; i < LICENSE_STR_IMPORTANT_CHARS + 1; i ++)
buf[i] = 0;
for (i = 0; i < LICENSE_STR_NIBBLES; i ++)
License_encipher ((PULONG) (buf + i * LICENSE_DATA_GRANULARITY),
(PULONG) str_key);
for (i = 0, code = 0; i < LICENSE_STR_NIBBLES; i ++)
{
nibp = (PULONG) (buf + (i * LICENSE_DATA_GRANULARITY));
code ^= nibp [0] ^ nibp [1];
}
/* V2.2 - if password consists of the same characters - XORing nibbles
above makes it go to 0 - put some recovery for that special case since
we cannot modify the algorithm due to legacy issues */
if (code == 0 && str [0] != 0)
code = * ((PULONG) buf);
return code;
} /* License_wstring_encode */
BOOL License_data_encode (
PCHAR data,
ULONG len)
{
ULONG i;
if (len % LICENSE_DATA_GRANULARITY != 0)
return FALSE;
for (i = 0; i < len; i += LICENSE_DATA_GRANULARITY)
License_encipher ((PULONG) (data + i), (PULONG) data_key);
return TRUE;
} /* License_data_encode */