//+----------------------------------------------------------------------- // // Microsoft Windows // // Copyright (c) Microsoft Corporation 1992 - 1992 // // File: cryptest.cxx // // Contents: test program to test encryption functions // // // History: 07-Oct-1996 MikeSw Created // //------------------------------------------------------------------------ extern "C" { #include #include #include #include #define SECURITY_WIN32 #include #include #include #include #include #include #include #include "md5.h" } typedef enum _CRYPT_ACTIONS { HashPassword, EncryptData, ChecksumData, EnumTypes, NoAction } CRYPT_ACTIONS; VOID DoMd5( PUCHAR Buffer, ULONG BufferLength ) { MD5_CTX Md5Context; MD5Init(&Md5Context); MD5Update(&Md5Context, Buffer, BufferLength); MD5Final(&Md5Context); } void _cdecl main(int argc, char *argv[]) { NTSTATUS Status; UNICODE_STRING Password; UNICODE_STRING User; UNICODE_STRING Domain; UNICODE_STRING Salt; ULONG CryptType = 0; ULONG HashType = 0; ULONG SumType = 0; WCHAR PasswordBuffer[100]; WCHAR UserBuffer[100]; WCHAR DomainBuffer[100]; KERB_ACCOUNT_TYPE AccountType = UserAccount; CRYPT_ACTIONS Command = NoAction; int Index; ULONG uI; KERB_ENCRYPTION_KEY Key; KERBERR KerbErr; ULONG BlockSize; ULONG Overhead; ULONG BufferLength; ULONG ReqBufferLength; UCHAR OriginalBuffer[1000]; PUCHAR EncryptedBuffer = NULL; PUCHAR DecryptedBuffer = NULL; PCRYPTO_SYSTEM Crypto; PCRYPT_STATE_BUFFER StateBuffer = NULL; Index = 1; while (Index < argc) { if (_stricmp(argv[Index],"-hash") == 0) { Command = HashPassword; if (argc < Index+1) { goto Cleanup; } sscanf(argv[++Index],"%d",&HashType); } else if (_stricmp(argv[Index],"-pass") == 0) { if (argc < Index + 1) { goto Cleanup; } mbstowcs(PasswordBuffer,argv[++Index],100); RtlInitUnicodeString( &Password, PasswordBuffer ); } else if (_stricmp(argv[Index],"-user") == 0) { if (argc < Index + 1) { goto Cleanup; } mbstowcs(UserBuffer,argv[++Index],100); RtlInitUnicodeString( &User, UserBuffer ); } else if (_stricmp(argv[Index],"-domain") == 0) { if (argc < Index + 1) { goto Cleanup; } mbstowcs(DomainBuffer,argv[++Index],100); RtlInitUnicodeString( &Domain, DomainBuffer ); } else if (_stricmp(argv[Index],"-type") == 0) { if (argc < Index + 1) { goto Cleanup; } if (_stricmp(argv[Index+1],"user") == 0) { AccountType = UserAccount; } else if (_stricmp(argv[Index+1],"machine") == 0) { AccountType = MachineAccount; } else if (_stricmp(argv[Index+1],"domain") == 0) { AccountType = DomainTrustAccount; } else { printf("Illegal account type: %s\n",argv[Index+1]); goto Cleanup; } Index++; } else if (_stricmp(argv[Index],"-crypt") == 0) { Command = EncryptData; if (argc < Index + 1) { goto Cleanup; } sscanf(argv[++Index],"%d",&CryptType); } else if (_stricmp(argv[Index],"-sum") == 0) { Command = ChecksumData; if (argc < Index + 1) { goto Cleanup; } sscanf(argv[++Index],"%d",&SumType); } else if (_stricmp(argv[Index],"-enum") == 0) { Command = EnumTypes; } else { goto Cleanup; } Index++; } if (Command == NoAction) { goto Cleanup; } switch(Command) { case EnumTypes: break; case HashPassword: KerbErr = KerbBuildKeySalt( &Domain, &User, AccountType, &Salt ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to build key salt: 0x%x\n",KerbErr); goto Cleanup; } printf("KeySalt = %wZ\n",&Salt); KerbErr = KerbHashPasswordEx( &Password, &Salt, HashType, &Key ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to hash password: 0x%x\n",KerbErr); goto Exit; } printf("Hash: "); for (uI = 0; uI < Key.keyvalue.length ; uI++ ) { printf("%0.2x ",Key.keyvalue.value[uI]); } printf("\n"); break; case EncryptData: // // First hash the password // KerbErr= KerbHashPassword( &Password, CryptType, &Key ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to hash password: %0x%x\n",KerbErr); goto Exit; } KerbErr = KerbGetEncryptionOverhead( CryptType, &Overhead, &BlockSize ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to get enc overhead: 0x%x\n",KerbErr); goto Exit; } BufferLength = sizeof(OriginalBuffer); memset(OriginalBuffer,'A',BufferLength); #ifdef notdef KerbErr = KerbRandomFill( OriginalBuffer, BufferLength ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to init random buffer: 0x%x\n",KerbErr); goto Exit; } #endif ReqBufferLength = ROUND_UP_COUNT(BufferLength + Overhead, BlockSize); EncryptedBuffer = (PUCHAR) LocalAlloc(LMEM_ZEROINIT, ReqBufferLength); if (EncryptedBuffer == NULL) { printf("Failed to allocate 0x%x bytes: %d\n",ReqBufferLength, GetLastError()); goto Exit; } Status = CDLocateCSystem( CryptType, &Crypto ); if (!NT_SUCCESS(Status)) { printf("Failed to locate crypt system 0x%x: 0x%x\n",CryptType,Status); goto Exit; } Status = Crypto->Initialize( Key.keyvalue.value, (ULONG) Key.keyvalue.length, 0, // no options &StateBuffer ); if (!NT_SUCCESS(Status)) { printf("failed to initialize crypto system: 0x%x\n",Status); goto Exit; } Status = Crypto->Encrypt( StateBuffer, OriginalBuffer, BufferLength, EncryptedBuffer, &ReqBufferLength ); if (!NT_SUCCESS(Status)) { printf("Failed to encrypt data: 0x%x\n",Status); goto Exit; } Status = Crypto->Discard(&StateBuffer); if (!NT_SUCCESS(Status)) { printf("Failed to discard state buffer: 0x%x\n",Status); goto Exit; } // // Now turn around and decrypt it. // DecryptedBuffer = (PUCHAR) LocalAlloc(LMEM_ZEROINIT, ReqBufferLength); if (EncryptedBuffer == NULL) { printf("Failed to allocate 0x%x bytes: %d\n",ReqBufferLength, GetLastError()); goto Exit; } Status = Crypto->Initialize( Key.keyvalue.value, (ULONG) Key.keyvalue.length, 0, // no options &StateBuffer ); if (!NT_SUCCESS(Status)) { printf("failed to initialize crypto system: 0x%x\n",Status); goto Exit; } Status = Crypto->Decrypt( StateBuffer, EncryptedBuffer, ReqBufferLength, DecryptedBuffer, &ReqBufferLength ); if (!NT_SUCCESS(Status)) { printf("Failed to decrypt data: 0x%x\n",Status); goto Exit; } Status = Crypto->Discard(&StateBuffer); if (!NT_SUCCESS(Status)) { printf("Failed to discard state buffer: 0x%x\n",Status); goto Exit; } // // Now compare // if (!RtlEqualMemory( OriginalBuffer, DecryptedBuffer, BufferLength )) { printf("Buffers don't match!\n"); } else { printf("Encryption/decryption succeeded!\n"); } break; case ChecksumData: BufferLength = sizeof(OriginalBuffer); memset(OriginalBuffer,'A',BufferLength); DoMd5(OriginalBuffer,BufferLength); } Exit: return; Cleanup: printf("Usage: %s { -crypt cryptalg -sum sumtype -hash cryptalg -enum } -pass password -user user -domain domain -type accounttype \n", argv[0]); return; }