mirror of https://github.com/lianthony/NT4.0
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.
820 lines
26 KiB
820 lines
26 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ct1.c
|
|
|
|
Abstract:
|
|
|
|
Automatic component test program for NT ecnryption library
|
|
|
|
Author:
|
|
|
|
David Chalmers (Davidc) 10-21-91
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <crypt.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include "ctutil.h"
|
|
|
|
#define END_TO_END_ITERATIONS 100
|
|
#define MAX_DATA_LENGTH 42 // Maximum length data block for end-end test
|
|
|
|
|
|
BOOLEAN Success;
|
|
|
|
|
|
VOID
|
|
GenerateRandomBlock(
|
|
PCLEAR_BLOCK ClearBlock,
|
|
PULONG Seed)
|
|
{
|
|
*(&(((PULONG)ClearBlock)[0])) = RtlRandom(Seed);
|
|
*(&(((PULONG)ClearBlock)[1])) = RtlRandom(Seed);
|
|
}
|
|
|
|
VOID
|
|
GenerateRandomData(
|
|
PCLEAR_DATA ClearData,
|
|
PULONG Seed)
|
|
{
|
|
ULONG Index;
|
|
|
|
for (Index =0;
|
|
Index < (ClearData->MaximumLength - CLEAR_BLOCK_LENGTH);
|
|
Index += CLEAR_BLOCK_LENGTH) {
|
|
|
|
GenerateRandomBlock((PCLEAR_BLOCK)&(((PCHAR)(ClearData->Buffer))[Index]), Seed);
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
GenerateSeed(
|
|
PULONG Seed)
|
|
{
|
|
LARGE_INTEGER Time;
|
|
|
|
NtQuerySystemTime(&Time);
|
|
*Seed = ((PLONG)(&Time))[0] ^ ((PLONG)(&Time))[1];
|
|
}
|
|
|
|
|
|
VOID
|
|
GenerateRandomKey(
|
|
PBLOCK_KEY BlockKey,
|
|
PULONG Seed)
|
|
{
|
|
ULONG Data;
|
|
|
|
*(&(((PULONG)BlockKey)[0])) = RtlRandom(Seed);
|
|
Data = RtlRandom(Seed);
|
|
|
|
BlockKey->data[4] = (CHAR)(Data & 0xff);
|
|
BlockKey->data[5] = (CHAR)((Data >> 8 ) & 0xff);
|
|
BlockKey->data[6] = (CHAR)((Data >> 16) & 0xff);
|
|
}
|
|
|
|
|
|
VOID
|
|
GenerateRandomLmOwfPassword(
|
|
PLM_OWF_PASSWORD LmOwfPassword,
|
|
PULONG Seed)
|
|
{
|
|
GenerateRandomBlock((PCLEAR_BLOCK)&(LmOwfPassword->data[0]), Seed);
|
|
GenerateRandomBlock((PCLEAR_BLOCK)&(LmOwfPassword->data[1]), Seed);
|
|
}
|
|
|
|
|
|
VOID
|
|
GenerateRandomNtOwfPassword(
|
|
PNT_OWF_PASSWORD NtOwfPassword,
|
|
PULONG Seed)
|
|
{
|
|
ASSERT(sizeof(LM_OWF_PASSWORD) == sizeof(NT_OWF_PASSWORD));
|
|
|
|
GenerateRandomLmOwfPassword((PLM_OWF_PASSWORD)NtOwfPassword, Seed);
|
|
}
|
|
|
|
|
|
VOID
|
|
GenerateRandomLmSessionKey(
|
|
PLM_SESSION_KEY LmSessionKey,
|
|
PULONG Seed)
|
|
{
|
|
GenerateRandomBlock((PCLEAR_BLOCK)LmSessionKey, Seed);
|
|
}
|
|
|
|
|
|
VOID
|
|
GenerateRandomNtSessionKey(
|
|
PNT_SESSION_KEY NtSessionKey,
|
|
PULONG Seed)
|
|
{
|
|
ASSERT(sizeof(NT_SESSION_KEY) == sizeof(LM_SESSION_KEY));
|
|
|
|
GenerateRandomLmSessionKey((PLM_SESSION_KEY)NtSessionKey, Seed);
|
|
}
|
|
|
|
|
|
VOID
|
|
GenerateRandomUserSessionKey(
|
|
PUSER_SESSION_KEY UserSessionKey,
|
|
PULONG Seed)
|
|
{
|
|
ASSERT(sizeof(USER_SESSION_KEY) == sizeof(LM_OWF_PASSWORD));
|
|
|
|
GenerateRandomLmOwfPassword((PLM_OWF_PASSWORD)UserSessionKey, Seed);
|
|
}
|
|
|
|
|
|
VOID
|
|
GenerateRandomCryptIndex(
|
|
PCRYPT_INDEX CryptIndex,
|
|
PULONG Seed)
|
|
{
|
|
*CryptIndex = (CRYPT_INDEX)RtlRandom(Seed);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
TestEndToEnd(VOID)
|
|
{
|
|
// Test the block encryption routines end-to-end
|
|
|
|
int i;
|
|
ULONG Seed;
|
|
CLEAR_BLOCK ClearBlock1, ClearBlock2;
|
|
CYPHER_BLOCK CypherBlock;
|
|
BLOCK_KEY BlockKey;
|
|
|
|
CtPrint("Testing end-to-end block encryption/decryption...");
|
|
|
|
GenerateSeed(&Seed);
|
|
|
|
for (i=0; i < END_TO_END_ITERATIONS; i++) {
|
|
|
|
// Generate a random clearblock and blockkey
|
|
GenerateRandomBlock(&ClearBlock1, &Seed);
|
|
GenerateRandomKey(&BlockKey, &Seed);
|
|
|
|
// Encrypt and then decrypt block
|
|
RtlEncryptBlock(&ClearBlock1, &BlockKey, &CypherBlock);
|
|
RtlDecryptBlock(&CypherBlock, &BlockKey, &ClearBlock2);
|
|
|
|
if (!CtEqualClearBlock(&ClearBlock1, &ClearBlock2)) {
|
|
CtPrint("\n\rError - block did not decrypt to same value as original\n\r");
|
|
CtPrint("Clear Block :\n\r");
|
|
CtPrintClearBlocks(&ClearBlock1, 1);
|
|
CtPrint("Block Key :\n\r");
|
|
CtPrintBlockKeys(&BlockKey, 1);
|
|
CtPrint("Cypher Block :\n\r");
|
|
CtPrintCypherBlocks(&CypherBlock, 1);
|
|
CtPrint("Resulting Clear Block :\n\r");
|
|
CtPrintClearBlocks(&ClearBlock2, 1);
|
|
Success = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
CtPrint("Done.\n\r");
|
|
}
|
|
|
|
|
|
VOID
|
|
TestDataEndToEnd(VOID)
|
|
{
|
|
// Test the data encryption routines end-to-end
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG Seed;
|
|
CHAR ClearBuffer1[MAX_DATA_LENGTH], ClearBuffer2[MAX_DATA_LENGTH];
|
|
CLEAR_DATA ClearData1, ClearData2;
|
|
CHAR CypherBuffer[MAX_DATA_LENGTH + (CYPHER_BLOCK_LENGTH * 2)];
|
|
CYPHER_DATA CypherData;
|
|
CHAR KeyBuffer[MAX_DATA_LENGTH + (CYPHER_BLOCK_LENGTH * 2)];
|
|
DATA_KEY DataKey;
|
|
ULONG DataLength;
|
|
ULONG KeyLength;
|
|
CHAR BufferCheck;
|
|
|
|
CtPrint("\n\rTesting end-to-end data encryption/decryption...");
|
|
|
|
GenerateSeed(&Seed);
|
|
|
|
ClearData1.Buffer = ClearBuffer1 + 1;
|
|
ClearData1.MaximumLength = sizeof(ClearBuffer1) - 1;
|
|
ClearData2.Buffer = ClearBuffer2 + 1;
|
|
ClearData2.MaximumLength = sizeof(ClearBuffer2) - 1;
|
|
CypherData.Buffer = CypherBuffer + 1;
|
|
CypherData.MaximumLength = sizeof(CypherBuffer) - 1;
|
|
DataKey.Buffer = KeyBuffer + 1;
|
|
DataKey.MaximumLength = sizeof(KeyBuffer) - 1;
|
|
|
|
// Generate a random clearblock and blockkey
|
|
GenerateRandomData(&ClearData1, &Seed);
|
|
GenerateRandomData((PCLEAR_DATA)&DataKey, &Seed);
|
|
|
|
for (DataLength = 1; DataLength <= ClearData1.MaximumLength; DataLength ++) {
|
|
|
|
ClearData1.Length = DataLength;
|
|
|
|
for (KeyLength = 1; KeyLength <= BLOCK_KEY_LENGTH*2; KeyLength++) {
|
|
|
|
DataKey.Length = KeyLength;
|
|
|
|
// Encrypt and then decrypt data
|
|
CypherData.MaximumLength = 0;
|
|
Status = RtlEncryptData(&ClearData1, &DataKey, &CypherData);
|
|
ASSERT(Status == STATUS_BUFFER_TOO_SMALL);
|
|
ASSERT(CypherData.Length <= sizeof(CypherBuffer));
|
|
CypherData.MaximumLength = sizeof(CypherBuffer);
|
|
|
|
BufferCheck = ((PCHAR)CypherData.Buffer)[CypherData.Length];
|
|
Status = RtlEncryptData(&ClearData1, &DataKey, &CypherData);
|
|
if (!NT_SUCCESS(Status)) {
|
|
CtPrint("RtlEncryptData failed - status = 0x%lx\n\r", Status);
|
|
Success = FALSE;
|
|
break;
|
|
}
|
|
if (BufferCheck != ((PCHAR)CypherData.Buffer)[CypherData.Length]) {
|
|
CtPrint("RtlEncryptData wrote past end of buffer\n\r");
|
|
Success = FALSE;
|
|
break;
|
|
}
|
|
|
|
// Modify byte beyond end and start of encrypted data to check it's not used
|
|
((PCHAR)CypherData.Buffer)[CypherData.Length] --;
|
|
(*CypherBuffer) ++;
|
|
// Modify byte beyond end and start of key to check it's not used
|
|
((PCHAR)DataKey.Buffer)[DataKey.Length] --;
|
|
(*KeyBuffer) ++;
|
|
|
|
ClearData2.MaximumLength = 0;
|
|
Status = RtlDecryptData(&CypherData, &DataKey, &ClearData2);
|
|
ASSERT(Status == STATUS_BUFFER_TOO_SMALL);
|
|
ASSERT(ClearData2.Length <= sizeof(ClearBuffer2));
|
|
ClearData2.MaximumLength = sizeof(ClearBuffer2);
|
|
|
|
RtlFillMemory(ClearData2.Buffer, ClearData2.Length, 'f');
|
|
|
|
BufferCheck = ((PCHAR)ClearData2.Buffer)[ClearData2.Length];
|
|
Status = RtlDecryptData(&CypherData, &DataKey, &ClearData2);
|
|
if (!NT_SUCCESS(Status)) {
|
|
CtPrint("RtlDecryptData failed - status = 0x%lx\n\r", Status);
|
|
Success = FALSE;
|
|
break;
|
|
}
|
|
if (BufferCheck != ((PCHAR)ClearData2.Buffer)[ClearData2.Length]) {
|
|
CtPrint("RtlDecryptData wrote past end of buffer\n\r");
|
|
Success = FALSE;
|
|
break;
|
|
}
|
|
|
|
//DbgPrint("Clear length1 = %ld, cypher length = %ld, clear length2 = %ld\n\r",
|
|
// ClearData1.Length, CypherData.Length, ClearData2.Length);
|
|
|
|
if (!CtEqualClearData(&ClearData1, &ClearData2)) {
|
|
CtPrint("\n\rError - data did not decrypt to same value as original\n\r");
|
|
CtPrint("Clear Data :\n\r");
|
|
CtPrintClearData(&ClearData1);
|
|
CtPrint("Data Key :\n\r");
|
|
CtPrintDataKey(&DataKey);
|
|
CtPrint("Cypher Data :\n\r");
|
|
CtPrintCypherData(&CypherData);
|
|
CtPrint("Resulting Clear Data :\n\r");
|
|
CtPrintClearData(&ClearData2);
|
|
Success = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
CtPrint("Done.\n\r");
|
|
}
|
|
|
|
typedef struct {
|
|
LM_CHALLENGE LmChallenge;
|
|
PLM_PASSWORD LmPassword;
|
|
LM_RESPONSE LmResponse;
|
|
} LMTESTCASE;
|
|
|
|
|
|
VOID
|
|
TestLMCompat(VOID)
|
|
{
|
|
LM_RESPONSE LmResponse;
|
|
int i;
|
|
|
|
|
|
LMTESTCASE testcases[] = {
|
|
|
|
{ // Test-case 0
|
|
|
|
{ 0x15, 0x24, 0xd3, 0x16, 0x58, 0xc0, 0xe6, 0xc6 }, // challenge
|
|
{ "NG4200" }, // password
|
|
{ 0x8e, 0x45, 0x82, 0x3d, 0xd2, 0xdb, 0x5b, 0x3a, // response
|
|
0x05, 0x8d, 0x88, 0x9e, 0x6e, 0x19, 0xe8, 0xc8, // response
|
|
0xb8, 0xd6, 0xa8, 0x13, 0xfd, 0x54, 0x84, 0x0c }, // response
|
|
},
|
|
{ // Test-case 1
|
|
|
|
{ 0x84, 0x58, 0xcf, 0x54, 0x79, 0x09, 0x0a, 0xbe }, // challenge
|
|
{ "A" }, // password
|
|
{ 0x3b, 0x43, 0xf7, 0x83, 0x65, 0xdd, 0x5d, 0xf9, // response
|
|
0xd1, 0x50, 0x4b, 0x55, 0x37, 0x8d, 0x9e, 0x58, // response
|
|
0x57, 0xea, 0xe5, 0x7b, 0xfc, 0x02, 0x29, 0x08 }, // response
|
|
},
|
|
{ // Test-case 2
|
|
|
|
{ 0x9d, 0x5b, 0x20, 0x48, 0xa4, 0x37, 0x4e, 0xf4 }, // challenge
|
|
{ "01234567890123" }, // password
|
|
{ 0xe9, 0x93, 0xdf, 0x31, 0xd0, 0xa1, 0xba, 0x97, // response
|
|
0x53, 0x32, 0x36, 0x1e, 0x8f, 0x76, 0x13, 0xe2, // response
|
|
0x60, 0xf9, 0xfe, 0xfa, 0x70, 0xf0, 0xb1, 0x0d }, // response
|
|
},
|
|
{ // Test-case 3
|
|
|
|
{ 0x9a, 0x33, 0xd1, 0x05, 0xce, 0x1b, 0xbe, 0x29 }, // challenge
|
|
{ "0123456" }, // password
|
|
{ 0x3f, 0x45, 0x9a, 0xd8, 0x60, 0xa1, 0xec, 0xe9, // response
|
|
0x2d, 0x20, 0x4a, 0x26, 0xba, 0x3c, 0x5f, 0x08, // response
|
|
0xde, 0x77, 0x35, 0x89, 0x40, 0x33, 0x04, 0x90 }, // response
|
|
},
|
|
{ // Test-case 4
|
|
|
|
{ 0xd3, 0xcb, 0x73, 0x6e, 0xb9, 0xdc, 0xe0, 0x1b }, // challenge
|
|
{ "A" }, // a // password
|
|
{ 0x1e, 0xc7, 0x15, 0x96, 0x0c, 0xf6, 0x2d, 0xb7, // response
|
|
0x55, 0xd4, 0x1f, 0xf9, 0x9a, 0xae, 0xc2, 0x7d, // response
|
|
0xab, 0x52, 0x50, 0xc8, 0xe9, 0x80, 0xae, 0x7d }, // response
|
|
},
|
|
{ // Test-case 5
|
|
|
|
{ 0x20, 0xed, 0x5a, 0x52, 0x75, 0x6a, 0x4c, 0xc0 }, // challenge
|
|
{ "SUPER" }, // Super // password
|
|
{ 0xe2, 0xeb, 0xd4, 0xbb, 0x0f, 0xe1, 0x0d, 0x90, // response
|
|
0x0f, 0x9a, 0x86, 0x48, 0x85, 0xa3, 0x30, 0xba, // response
|
|
0xa7, 0x9d, 0x21, 0xd8, 0x6d, 0xf6, 0xa7, 0xa4 }, // response
|
|
},
|
|
{ // Test-case 6
|
|
|
|
{ 0x9a, 0x8a, 0xee, 0x3d, 0xe5, 0xa1, 0x48, 0xb4 }, // challenge
|
|
{ "SUPER003CALIFR" }, // Super003Califr // password
|
|
{ 0x6d, 0x19, 0xd9, 0x56, 0x87, 0xc9, 0xbf, 0x70, // response
|
|
0x3d, 0x24, 0x91, 0x01, 0x20, 0x29, 0x1f, 0xa5, // response
|
|
0x12, 0xfc, 0xf0, 0xa4, 0xf3, 0xd7, 0x0a, 0x0b }, // response
|
|
}
|
|
};
|
|
|
|
CtPrint("\n\rRunning Lanman test-cases...");
|
|
|
|
// Run through each test-case
|
|
for (i=0; i < sizeof(testcases)/sizeof(LMTESTCASE); i++) {
|
|
|
|
LM_OWF_PASSWORD LmOwfPassword;
|
|
|
|
RtlCalculateLmOwfPassword(testcases[i].LmPassword, &LmOwfPassword);
|
|
|
|
RtlCalculateLmResponse(&testcases[i].LmChallenge, &LmOwfPassword, &LmResponse);
|
|
|
|
if (!CtEqualLmResponse(&LmResponse, &testcases[i].LmResponse)) {
|
|
|
|
CtPrint("\n\rTest-case %d failed...\n\r", i);
|
|
CtPrint("LmChallenge :\n\r");
|
|
CtPrintLmChallenge(&testcases[i].LmChallenge);
|
|
CtPrint("LmPassword :\n\r");
|
|
CtPrintLmPassword(testcases[i].LmPassword);
|
|
CtPrint("Expected LmResponse :\n\r");
|
|
CtPrintLmResponse(&testcases[i].LmResponse);
|
|
CtPrint("Actual LmResponse :\n\r");
|
|
CtPrintLmResponse(&LmResponse);
|
|
|
|
Success = FALSE;
|
|
}
|
|
}
|
|
|
|
CtPrint("Done\n\r");
|
|
}
|
|
|
|
typedef struct {
|
|
WCHAR * UnicodePassword;
|
|
NT_OWF_PASSWORD NtOwfPassword;
|
|
} NTTESTCASE;
|
|
|
|
VOID
|
|
TestNTCompat(VOID)
|
|
{
|
|
int i;
|
|
|
|
|
|
NTTESTCASE testcases[] = {
|
|
|
|
#ifndef MIPS
|
|
// LATER -- MIPS compiler can't handle multiple test-cases for some reason
|
|
{ // Test-case 0
|
|
|
|
{ L"a" }, // password
|
|
{ 0x18, 0x6c, 0xb0, 0x91, 0x81, 0xe2, 0xc2, 0xec, // owf password
|
|
0xaa, 0xc7, 0x68, 0xc4, 0x7c, 0x72, 0x99, 0x04 }, // owf password
|
|
},
|
|
{ // Test-case 1
|
|
|
|
{ NULL }, // password
|
|
{ 0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, // owf password
|
|
0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0 }, // owf password
|
|
},
|
|
{ // Test-case 2
|
|
|
|
{ L"A" }, // password
|
|
{ 0xc5, 0xdd, 0x1c, 0x2b, 0xc8, 0x71, 0x9c, 0x01, // owf password
|
|
0xb2, 0x5b, 0x4e, 0xb2, 0x69, 0x2c, 0x9f, 0xee }, // owf password
|
|
},
|
|
{ // Test-case 3
|
|
|
|
{ L"Supercalifragilistic" }, // password
|
|
{ 0x4d, 0x77, 0x81, 0x48, 0xe5, 0x7f, 0x51, 0x67, // owf password
|
|
0xad, 0x68, 0xc5, 0xd7, 0xee, 0x33, 0x41, 0x77 }, // owf password
|
|
},
|
|
#endif
|
|
{ // Test-case 4
|
|
|
|
{ L"SupercalifragilisticExpialidocious" }, // password
|
|
{ 0xa8, 0xf2, 0x01, 0x3d, 0x85, 0x93, 0x76, 0x16, // owf password
|
|
0x5a, 0xb3, 0x84, 0x8e, 0xd3, 0xae, 0x84, 0xb5 }, // owf password
|
|
}
|
|
};
|
|
|
|
CtPrint("\n\rRunning NT test-cases...");
|
|
|
|
// Run through each test-case
|
|
for (i=0; i < sizeof(testcases)/sizeof(NTTESTCASE); i++) {
|
|
|
|
NT_PASSWORD NtPassword;
|
|
NT_OWF_PASSWORD NtOwfPassword;
|
|
|
|
RtlInitUnicodeString(&NtPassword, testcases[i].UnicodePassword);
|
|
|
|
RtlCalculateNtOwfPassword(&NtPassword, &NtOwfPassword);
|
|
|
|
if (!CtEqualNtOwfPassword(&NtOwfPassword, &testcases[i].NtOwfPassword)) {
|
|
|
|
CtPrint("\n\rTest-case %d failed...\n\r", i);
|
|
CtPrint("NtPassword :\n\r");
|
|
CtPrintNtPassword(&NtPassword);
|
|
CtPrint("Expected NtOwfPassword :\n\r");
|
|
CtPrintNtOwfPassword(&testcases[i].NtOwfPassword);
|
|
CtPrint("Actual NtOwfPassword :\n\r");
|
|
CtPrintNtOwfPassword(&NtOwfPassword);
|
|
|
|
Success = FALSE;
|
|
}
|
|
}
|
|
|
|
CtPrint("Done\n\r");
|
|
}
|
|
|
|
|
|
VOID
|
|
TestLMOWFCrypt(VOID)
|
|
{
|
|
int i;
|
|
ULONG Seed;
|
|
|
|
GenerateSeed(&Seed);
|
|
|
|
CtPrint("\n\rTesting LMOWFPassword encryption/decryption with LMOWFPassword...");
|
|
|
|
for (i=0; i < END_TO_END_ITERATIONS; i++) {
|
|
|
|
LM_OWF_PASSWORD OwfPasswordData1;
|
|
LM_OWF_PASSWORD OwfPasswordData2;
|
|
LM_OWF_PASSWORD OwfPasswordKey;
|
|
ENCRYPTED_LM_OWF_PASSWORD EncryptedOwfPassword;
|
|
|
|
// Generate two random OWFPasswords
|
|
GenerateRandomLmOwfPassword(&OwfPasswordData1, &Seed);
|
|
GenerateRandomLmOwfPassword(&OwfPasswordKey, &Seed);
|
|
|
|
// Encrypt and then decrypt block
|
|
RtlEncryptLmOwfPwdWithLmOwfPwd(&OwfPasswordData1, &OwfPasswordKey, &EncryptedOwfPassword);
|
|
RtlDecryptLmOwfPwdWithLmOwfPwd(&EncryptedOwfPassword, &OwfPasswordKey, &OwfPasswordData2);
|
|
|
|
if (!CtEqualLmOwfPassword(&OwfPasswordData1, &OwfPasswordData2)) {
|
|
CtPrint("\n\rError - OWFPassword did not decrypt to same value as original\n\r");
|
|
CtPrint("LmOwfPasswordData :\n\r");
|
|
CtPrintLmOwfPassword(&OwfPasswordData1);
|
|
CtPrint("LmOwfPasswordKey :\n\r");
|
|
CtPrintLmOwfPassword(&OwfPasswordKey);
|
|
CtPrint("EncryptedLmOwfPassword :\n\r");
|
|
CtPrintEncryptedLmOwfPassword(&EncryptedOwfPassword);
|
|
CtPrint("Resulting LmOwfPassword :\n\r");
|
|
CtPrintLmOwfPassword(&OwfPasswordData2);
|
|
Success = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
CtPrint("Done.\n\r");
|
|
|
|
|
|
|
|
CtPrint("\n\rTesting LMOWFPassword encryption/decryption with LM Session Key...");
|
|
|
|
for (i=0; i < END_TO_END_ITERATIONS; i++) {
|
|
|
|
LM_OWF_PASSWORD OwfPassword1;
|
|
LM_OWF_PASSWORD OwfPassword2;
|
|
LM_SESSION_KEY SessionKey;
|
|
ENCRYPTED_LM_OWF_PASSWORD EncryptedOwfPassword;
|
|
|
|
// Generate a random OWFPassword and random session key
|
|
GenerateRandomLmOwfPassword(&OwfPassword1, &Seed);
|
|
GenerateRandomLmSessionKey(&SessionKey, &Seed);
|
|
|
|
// Encrypt and then decrypt OwfPassword
|
|
RtlEncryptLmOwfPwdWithLmSesKey(&OwfPassword1, &SessionKey, &EncryptedOwfPassword);
|
|
RtlDecryptLmOwfPwdWithLmSesKey(&EncryptedOwfPassword, &SessionKey, &OwfPassword2);
|
|
|
|
if (!CtEqualLmOwfPassword(&OwfPassword1, &OwfPassword2)) {
|
|
CtPrint("\n\rError - OWFPassword did not decrypt to same value as original\n\r");
|
|
CtPrint("LmOwfPassword :\n\r");
|
|
CtPrintLmOwfPassword(&OwfPassword1);
|
|
CtPrint("LmSessionKey :\n\r");
|
|
CtPrintLmSessionKey(&SessionKey);
|
|
CtPrint("EncryptedLmOwfPassword :\n\r");
|
|
CtPrintEncryptedLmOwfPassword(&EncryptedOwfPassword);
|
|
CtPrint("Resulting LmOwfPassword :\n\r");
|
|
CtPrintLmOwfPassword(&OwfPassword2);
|
|
Success = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
CtPrint("Done.\n\r");
|
|
|
|
|
|
CtPrint("\n\rTesting LMOWFPassword encryption/decryption with User Session Key...");
|
|
|
|
for (i=0; i < END_TO_END_ITERATIONS; i++) {
|
|
|
|
LM_OWF_PASSWORD OwfPassword1;
|
|
LM_OWF_PASSWORD OwfPassword2;
|
|
USER_SESSION_KEY UserSessionKey;
|
|
ENCRYPTED_LM_OWF_PASSWORD EncryptedOwfPassword;
|
|
|
|
// Generate a random OWFPassword and random session key
|
|
GenerateRandomLmOwfPassword(&OwfPassword1, &Seed);
|
|
GenerateRandomUserSessionKey(&UserSessionKey, &Seed);
|
|
|
|
// Encrypt and then decrypt OwfPassword
|
|
RtlEncryptLmOwfPwdWithUserKey(&OwfPassword1, &UserSessionKey, &EncryptedOwfPassword);
|
|
RtlDecryptLmOwfPwdWithUserKey(&EncryptedOwfPassword, &UserSessionKey, &OwfPassword2);
|
|
|
|
if (!CtEqualLmOwfPassword(&OwfPassword1, &OwfPassword2)) {
|
|
CtPrint("\n\rError - OWFPassword did not decrypt to same value as original\n\r");
|
|
CtPrint("LmOwfPassword :\n\r");
|
|
CtPrintLmOwfPassword(&OwfPassword1);
|
|
CtPrint("LmSessionKey :\n\r");
|
|
CtPrintUserSessionKey(&UserSessionKey);
|
|
CtPrint("EncryptedLmOwfPassword :\n\r");
|
|
CtPrintEncryptedLmOwfPassword(&EncryptedOwfPassword);
|
|
CtPrint("Resulting LmOwfPassword :\n\r");
|
|
CtPrintLmOwfPassword(&OwfPassword2);
|
|
Success = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
CtPrint("Done.\n\r");
|
|
|
|
|
|
|
|
CtPrint("\n\rTesting LMOWFPassword encryption/decryption with Index...");
|
|
|
|
for (i=0; i < END_TO_END_ITERATIONS; i++) {
|
|
|
|
LM_OWF_PASSWORD OwfPassword1;
|
|
LM_OWF_PASSWORD OwfPassword2;
|
|
CRYPT_INDEX Index;
|
|
ENCRYPTED_LM_OWF_PASSWORD EncryptedOwfPassword;
|
|
|
|
// Generate a random OWFPassword and index
|
|
GenerateRandomLmOwfPassword(&OwfPassword1, &Seed);
|
|
GenerateRandomCryptIndex(&Index, &Seed);
|
|
|
|
// Encrypt and then decrypt OwfPassword
|
|
RtlEncryptLmOwfPwdWithIndex(&OwfPassword1, &Index, &EncryptedOwfPassword);
|
|
RtlDecryptLmOwfPwdWithIndex(&EncryptedOwfPassword, &Index, &OwfPassword2);
|
|
|
|
if (!CtEqualLmOwfPassword(&OwfPassword1, &OwfPassword2)) {
|
|
CtPrint("\n\rError - OWFPassword did not decrypt to same value as original\n\r");
|
|
CtPrint("LmOwfPassword :\n\r");
|
|
CtPrintLmOwfPassword(&OwfPassword1);
|
|
CtPrint("Index :\n\r");
|
|
CtPrintCryptIndex(&Index);
|
|
CtPrint("EncryptedLmOwfPassword :\n\r");
|
|
CtPrintEncryptedLmOwfPassword(&EncryptedOwfPassword);
|
|
CtPrint("Resulting LmOwfPassword :\n\r");
|
|
CtPrintLmOwfPassword(&OwfPassword2);
|
|
Success = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
CtPrint("Done.\n\r");
|
|
}
|
|
|
|
|
|
VOID
|
|
TestNTOWFCrypt(VOID)
|
|
{
|
|
int i;
|
|
ULONG Seed;
|
|
|
|
GenerateSeed(&Seed);
|
|
|
|
CtPrint("\n\rTesting NTOWFPassword encryption/decryption with NTOWFPassword...");
|
|
|
|
for (i=0; i < END_TO_END_ITERATIONS; i++) {
|
|
|
|
NT_OWF_PASSWORD OwfPasswordData1;
|
|
NT_OWF_PASSWORD OwfPasswordData2;
|
|
NT_OWF_PASSWORD OwfPasswordKey;
|
|
ENCRYPTED_NT_OWF_PASSWORD EncryptedOwfPassword;
|
|
|
|
// Generate two random OWFPasswords
|
|
GenerateRandomNtOwfPassword(&OwfPasswordData1, &Seed);
|
|
GenerateRandomNtOwfPassword(&OwfPasswordKey, &Seed);
|
|
|
|
// Encrypt and then decrypt block
|
|
RtlEncryptNtOwfPwdWithNtOwfPwd(&OwfPasswordData1, &OwfPasswordKey, &EncryptedOwfPassword);
|
|
RtlDecryptNtOwfPwdWithNtOwfPwd(&EncryptedOwfPassword, &OwfPasswordKey, &OwfPasswordData2);
|
|
|
|
if (!CtEqualNtOwfPassword(&OwfPasswordData1, &OwfPasswordData2)) {
|
|
CtPrint("\n\rError - OWFPassword did not decrypt to same value as original\n\r");
|
|
CtPrint("NtOwfPasswordData :\n\r");
|
|
CtPrintNtOwfPassword(&OwfPasswordData1);
|
|
CtPrint("NtOwfPasswordKey :\n\r");
|
|
CtPrintNtOwfPassword(&OwfPasswordKey);
|
|
CtPrint("EncryptedNtOwfPassword :\n\r");
|
|
CtPrintEncryptedNtOwfPassword(&EncryptedOwfPassword);
|
|
CtPrint("Resulting NtOwfPassword :\n\r");
|
|
CtPrintNtOwfPassword(&OwfPasswordData2);
|
|
Success = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
CtPrint("Done.\n\r");
|
|
|
|
|
|
|
|
CtPrint("\n\rTesting NTOWFPassword encryption/decryption with NT Session Key...");
|
|
|
|
for (i=0; i < END_TO_END_ITERATIONS; i++) {
|
|
|
|
NT_OWF_PASSWORD OwfPassword1;
|
|
NT_OWF_PASSWORD OwfPassword2;
|
|
NT_SESSION_KEY SessionKey;
|
|
ENCRYPTED_NT_OWF_PASSWORD EncryptedOwfPassword;
|
|
|
|
// Generate a random OWFPassword and random session key
|
|
GenerateRandomNtOwfPassword(&OwfPassword1, &Seed);
|
|
GenerateRandomNtSessionKey(&SessionKey, &Seed);
|
|
|
|
// Encrypt and then decrypt OwfPassword
|
|
RtlEncryptNtOwfPwdWithNtSesKey(&OwfPassword1, &SessionKey, &EncryptedOwfPassword);
|
|
RtlDecryptNtOwfPwdWithNtSesKey(&EncryptedOwfPassword, &SessionKey, &OwfPassword2);
|
|
|
|
if (!CtEqualNtOwfPassword(&OwfPassword1, &OwfPassword2)) {
|
|
CtPrint("\n\rError - OWFPassword did not decrypt to same value as original\n\r");
|
|
CtPrint("NtOwfPassword :\n\r");
|
|
CtPrintNtOwfPassword(&OwfPassword1);
|
|
CtPrint("NtSessionKey :\n\r");
|
|
CtPrintNtSessionKey(&SessionKey);
|
|
CtPrint("EncryptedNtOwfPassword :\n\r");
|
|
CtPrintEncryptedNtOwfPassword(&EncryptedOwfPassword);
|
|
CtPrint("Resulting NtOwfPassword :\n\r");
|
|
CtPrintNtOwfPassword(&OwfPassword2);
|
|
Success = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
CtPrint("Done.\n\r");
|
|
|
|
|
|
CtPrint("\n\rTesting NTOWFPassword encryption/decryption with User Session Key...");
|
|
|
|
for (i=0; i < END_TO_END_ITERATIONS; i++) {
|
|
|
|
NT_OWF_PASSWORD OwfPassword1;
|
|
NT_OWF_PASSWORD OwfPassword2;
|
|
USER_SESSION_KEY UserSessionKey;
|
|
ENCRYPTED_NT_OWF_PASSWORD EncryptedOwfPassword;
|
|
|
|
// Generate a random OWFPassword and random session key
|
|
GenerateRandomNtOwfPassword(&OwfPassword1, &Seed);
|
|
GenerateRandomUserSessionKey(&UserSessionKey, &Seed);
|
|
|
|
// Encrypt and then decrypt OwfPassword
|
|
RtlEncryptNtOwfPwdWithUserKey(&OwfPassword1, &UserSessionKey, &EncryptedOwfPassword);
|
|
RtlDecryptNtOwfPwdWithUserKey(&EncryptedOwfPassword, &UserSessionKey, &OwfPassword2);
|
|
|
|
if (!CtEqualNtOwfPassword(&OwfPassword1, &OwfPassword2)) {
|
|
CtPrint("\n\rError - OWFPassword did not decrypt to same value as original\n\r");
|
|
CtPrint("NtOwfPassword :\n\r");
|
|
CtPrintNtOwfPassword(&OwfPassword1);
|
|
CtPrint("NtSessionKey :\n\r");
|
|
CtPrintUserSessionKey(&UserSessionKey);
|
|
CtPrint("EncryptedNtOwfPassword :\n\r");
|
|
CtPrintEncryptedNtOwfPassword(&EncryptedOwfPassword);
|
|
CtPrint("Resulting NtOwfPassword :\n\r");
|
|
CtPrintNtOwfPassword(&OwfPassword2);
|
|
Success = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
CtPrint("Done.\n\r");
|
|
|
|
|
|
|
|
CtPrint("\n\rTesting NTOWFPassword encryption/decryption with Index...");
|
|
|
|
for (i=0; i < END_TO_END_ITERATIONS; i++) {
|
|
|
|
NT_OWF_PASSWORD OwfPassword1;
|
|
NT_OWF_PASSWORD OwfPassword2;
|
|
CRYPT_INDEX Index;
|
|
ENCRYPTED_NT_OWF_PASSWORD EncryptedOwfPassword;
|
|
|
|
// Generate a random OWFPassword and index
|
|
GenerateRandomNtOwfPassword(&OwfPassword1, &Seed);
|
|
GenerateRandomCryptIndex(&Index, &Seed);
|
|
|
|
// Encrypt and then decrypt OwfPassword
|
|
RtlEncryptNtOwfPwdWithIndex(&OwfPassword1, &Index, &EncryptedOwfPassword);
|
|
RtlDecryptNtOwfPwdWithIndex(&EncryptedOwfPassword, &Index, &OwfPassword2);
|
|
|
|
if (!CtEqualNtOwfPassword(&OwfPassword1, &OwfPassword2)) {
|
|
CtPrint("\n\rError - OWFPassword did not decrypt to same value as original\n\r");
|
|
CtPrint("NtOwfPassword :\n\r");
|
|
CtPrintNtOwfPassword(&OwfPassword1);
|
|
CtPrint("Index :\n\r");
|
|
CtPrintCryptIndex(&Index);
|
|
CtPrint("EncryptedNtOwfPassword :\n\r");
|
|
CtPrintEncryptedNtOwfPassword(&EncryptedOwfPassword);
|
|
CtPrint("Resulting NtOwfPassword :\n\r");
|
|
CtPrintNtOwfPassword(&OwfPassword2);
|
|
Success = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
CtPrint("Done.\n\r");
|
|
}
|
|
|
|
|
|
int _cdecl main (argc, argv)
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
Success = TRUE;
|
|
|
|
CtPrint("\n\r\n\r");
|
|
CtPrint("Beginning encryption component test\n\r");
|
|
CtPrint("===================================\n\r");
|
|
CtPrint("\n\r");
|
|
|
|
TestEndToEnd();
|
|
TestDataEndToEnd();
|
|
TestLMCompat();
|
|
TestNTCompat();
|
|
TestLMOWFCrypt();
|
|
TestNTOWFCrypt();
|
|
|
|
CtPrint("\n\rEncryption component test complete : ");
|
|
|
|
if (Success) {
|
|
CtPrint("PASSED\n\r");
|
|
} else {
|
|
CtPrint("FAILED\n\r");
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
|