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.
394 lines
8.9 KiB
394 lines
8.9 KiB
//+-----------------------------------------------------------------------
|
|
//
|
|
// File: crypt.c
|
|
//
|
|
// Contents: cryptography routines for building EncryptedData structs
|
|
//
|
|
//
|
|
// History: 17-Dec-91, RichardW Created
|
|
// 25-Feb-92, RichardW Revised for CryptoSystems
|
|
//
|
|
//------------------------------------------------------------------------
|
|
|
|
#ifndef WIN32_CHICAGO
|
|
#include "krbprgma.h"
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <kerbcomm.h>
|
|
#include <kerberr.h>
|
|
#include <kerbcon.h>
|
|
#else // WIN32_CHICAGO
|
|
#include <kerb.hxx>
|
|
#include <kerbp.h>
|
|
#endif // WIN32_CHICAGO
|
|
|
|
|
|
#define CONFOUNDER_SIZE 8
|
|
#define CHECKSUM_SIZE sizeof(CheckSum)
|
|
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: KerbEncryptData
|
|
//
|
|
// Synopsis: shim for KerbEncryptDataEx
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
KERBERR NTAPI
|
|
KerbEncryptData(
|
|
OUT PKERB_ENCRYPTED_DATA EncryptedData,
|
|
IN ULONG DataSize,
|
|
IN PUCHAR Data,
|
|
IN ULONG Algorithm,
|
|
IN PKERB_ENCRYPTION_KEY Key
|
|
)
|
|
{
|
|
return KerbEncryptDataEx(
|
|
EncryptedData,
|
|
DataSize,
|
|
Data,
|
|
KERB_NO_KEY_VERSION,
|
|
0, // no usage flags
|
|
Key
|
|
);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: KerbEncryptDataEx
|
|
//
|
|
// Synopsis: Turns cleartext into cipher text
|
|
//
|
|
// Effects: In place encryption of data
|
|
//
|
|
// Arguments: Data - Contains data to be encrypted
|
|
// DataSize - Contains length of data in bytes
|
|
// KeyVersion - KERB_NO_KEY_VERSION for no key version or kvno for KERB_ENCRYPTED_DATA
|
|
// Algorithm - Algorithm to be used for encryption/checksum
|
|
// UsageFlags - Flags indicating usage (client/serve, encryption/authentication)
|
|
// Key - Key to use for encryption
|
|
//
|
|
//
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
KERBERR NTAPI
|
|
KerbEncryptDataEx(
|
|
OUT PKERB_ENCRYPTED_DATA EncryptedData,
|
|
IN ULONG DataSize,
|
|
IN PUCHAR Data,
|
|
IN ULONG KeyVersion,
|
|
IN ULONG UsageFlags,
|
|
IN PKERB_ENCRYPTION_KEY Key
|
|
)
|
|
{
|
|
PCRYPTO_SYSTEM pcsCrypt = NULL;
|
|
PCRYPT_STATE_BUFFER psbCryptBuffer = NULL;
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
Status = CDLocateCSystem(Key->keytype, &pcsCrypt);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return(KDC_ERR_ETYPE_NOTSUPP);
|
|
}
|
|
|
|
//
|
|
// Initialize header
|
|
//
|
|
|
|
EncryptedData->encryption_type = Key->keytype;
|
|
|
|
Status = pcsCrypt->Initialize(
|
|
(PUCHAR) Key->keyvalue.value,
|
|
Key->keyvalue.length,
|
|
UsageFlags,
|
|
&psbCryptBuffer
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return(KRB_ERR_GENERIC);
|
|
}
|
|
|
|
Status = pcsCrypt->Encrypt(
|
|
psbCryptBuffer,
|
|
Data,
|
|
DataSize,
|
|
EncryptedData->cipher_text.value,
|
|
&EncryptedData->cipher_text.length
|
|
);
|
|
|
|
(void) pcsCrypt->Discard(&psbCryptBuffer);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return(KRB_ERR_GENERIC);
|
|
}
|
|
|
|
if (KeyVersion != KERB_NO_KEY_VERSION)
|
|
{
|
|
EncryptedData->version = KeyVersion;
|
|
EncryptedData->bit_mask |= version_present;
|
|
}
|
|
|
|
return(KDC_ERR_NONE);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: KerbDecryptData
|
|
//
|
|
// Synopsis: Shim for KerbDecryptDataEx with no usage flags
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
KERBERR NTAPI
|
|
KerbDecryptData(
|
|
IN PKERB_ENCRYPTED_DATA EncryptedData,
|
|
IN PKERB_ENCRYPTION_KEY pkKey,
|
|
OUT PULONG DataSize,
|
|
OUT PUCHAR Data
|
|
)
|
|
{
|
|
return(KerbDecryptDataEx(
|
|
EncryptedData,
|
|
pkKey,
|
|
0, // no usage flags
|
|
DataSize,
|
|
Data
|
|
) );
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: KerbDecryptDataEx
|
|
//
|
|
// Synopsis: Decrypts an EncryptedData structure
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments: [pedData] -- EncryptedData
|
|
// [pkKey] -- Key to use
|
|
//
|
|
// History: 4-16-93 RichardW Created Comment
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
KERBERR NTAPI
|
|
KerbDecryptDataEx(
|
|
IN PKERB_ENCRYPTED_DATA EncryptedData,
|
|
IN PKERB_ENCRYPTION_KEY pkKey,
|
|
IN ULONG UsageFlags,
|
|
OUT PULONG DataSize,
|
|
OUT PUCHAR Data
|
|
)
|
|
{
|
|
PCRYPTO_SYSTEM pcsCrypt = NULL;
|
|
PCRYPT_STATE_BUFFER psbCryptBuffer = NULL;
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
Status = CDLocateCSystem(
|
|
EncryptedData->encryption_type,
|
|
&pcsCrypt
|
|
);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return(KDC_ERR_ETYPE_NOTSUPP);
|
|
}
|
|
|
|
if (EncryptedData->cipher_text.length & (pcsCrypt->BlockSize - 1))
|
|
{
|
|
return(KRB_ERR_GENERIC);
|
|
}
|
|
|
|
|
|
Status = pcsCrypt->Initialize(
|
|
(PUCHAR) pkKey->keyvalue.value,
|
|
pkKey->keyvalue.length,
|
|
UsageFlags,
|
|
&psbCryptBuffer
|
|
);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return(KRB_ERR_GENERIC);
|
|
}
|
|
|
|
Status = pcsCrypt->Decrypt(
|
|
psbCryptBuffer,
|
|
EncryptedData->cipher_text.value,
|
|
EncryptedData->cipher_text.length,
|
|
Data,
|
|
DataSize
|
|
);
|
|
|
|
(VOID) pcsCrypt->Discard(&psbCryptBuffer);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return(KRB_AP_ERR_MODIFIED);
|
|
}
|
|
else
|
|
{
|
|
return(KDC_ERR_NONE);
|
|
}
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: KerbGetEncryptionOverhead
|
|
//
|
|
// Synopsis: Gets the extra space required for encryption to store the ckecksum
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments: Algorithm - the algorithm to use
|
|
// Overhead - receives the overhead in bytes
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns: STATUS_SUCCESS or KRB_E_ETYPE_NOSUPP
|
|
//
|
|
// Notes:
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
KERBERR
|
|
KerbGetEncryptionOverhead(
|
|
IN ULONG Algorithm,
|
|
OUT PULONG Overhead,
|
|
OUT OPTIONAL PULONG BlockSize
|
|
)
|
|
{
|
|
PCRYPTO_SYSTEM pcsCrypt;
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
Status = CDLocateCSystem(Algorithm, &pcsCrypt);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return(KDC_ERR_ETYPE_NOTSUPP);
|
|
}
|
|
*Overhead = pcsCrypt->HeaderSize;
|
|
if (ARGUMENT_PRESENT(BlockSize))
|
|
{
|
|
*BlockSize = pcsCrypt->BlockSize;
|
|
}
|
|
return(KDC_ERR_NONE);
|
|
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: KerbAllocateEncryptionBuffer
|
|
//
|
|
// Synopsis: Allocates the space required for encryption with a given
|
|
// key
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
KERBERR
|
|
KerbAllocateEncryptionBuffer(
|
|
IN ULONG EncryptionType,
|
|
IN ULONG BufferSize,
|
|
OUT PUINT EncryptionBufferSize,
|
|
OUT PBYTE * EncryptionBuffer
|
|
)
|
|
{
|
|
KERBERR KerbErr = KDC_ERR_NONE;
|
|
ULONG EncryptionOverhead = 0;
|
|
ULONG BlockSize = 0;
|
|
|
|
KerbErr = KerbGetEncryptionOverhead(
|
|
EncryptionType,
|
|
&EncryptionOverhead,
|
|
&BlockSize
|
|
);
|
|
if (!KERB_SUCCESS(KerbErr))
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
|
|
*EncryptionBufferSize = (UINT) ROUND_UP_COUNT(EncryptionOverhead + BufferSize, BlockSize);
|
|
|
|
*EncryptionBuffer = (PBYTE) MIDL_user_allocate(*EncryptionBufferSize);
|
|
if (*EncryptionBuffer == NULL)
|
|
{
|
|
KerbErr = KRB_ERR_GENERIC;
|
|
}
|
|
|
|
Cleanup:
|
|
return(KerbErr);
|
|
|
|
}
|
|
|
|
KERBERR
|
|
KerbAllocateEncryptionBufferWrapper(
|
|
IN ULONG EncryptionType,
|
|
IN ULONG BufferSize,
|
|
OUT unsigned long * EncryptionBufferSize,
|
|
OUT PBYTE * EncryptionBuffer
|
|
)
|
|
{
|
|
KERBERR KerbErr = KDC_ERR_NONE;
|
|
unsigned int tempInt = 0;
|
|
|
|
KerbErr = KerbAllocateEncryptionBuffer(
|
|
EncryptionType,
|
|
BufferSize,
|
|
&tempInt,
|
|
EncryptionBuffer
|
|
);
|
|
|
|
if (!KERB_SUCCESS(KerbErr))
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
*EncryptionBufferSize = tempInt;
|
|
|
|
Cleanup:
|
|
return (KerbErr);
|
|
}
|