//+----------------------------------------------------------------------- // // File: MDWRAP.C // // Contents: MDx Wrapper functions // // // History: 25 Feb 92, RichardW Created // //------------------------------------------------------------------------ #ifndef KERNEL_MODE #include #include #include #include #else #include #endif #include #include #include #include #include #ifdef WIN32_CHICAGO #include #undef ASSERT #define ASSERT(exp) assert(exp) #endif // WIN32_CHICAGO #include "md4.h" #include "md5.h" #include "des.h" typedef struct _MD5_DES_STATE_BUFFER { PCHECKSUM_BUFFER DesContext; MD5_CTX Md5Context; } MD5_DES_STATE_BUFFER, *PMD5_DES_STATE_BUFFER; typedef struct _MD5_DES_1510_STATE_BUFFER { PCHECKSUM_BUFFER DesContext; MD5_CTX Md5Context; UCHAR Confounder[DES_BLOCKLEN]; } MD5_DES_1510_STATE_BUFFER, *PMD5_DES_1510_STATE_BUFFER; typedef struct _MD5_HMAC_STATE_BUFFER { MD5_CTX Md5Context; ULONG KeySize; UCHAR Key[ANYSIZE_ARRAY]; } MD5_HMAC_STATE_BUFFER, *PMD5_HMAC_STATE_BUFFER; NTSTATUS NTAPI md4Initialize(ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI md4InitializeEx(PUCHAR,ULONG, ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI md4Sum(PCHECKSUM_BUFFER, ULONG, PUCHAR); NTSTATUS NTAPI md4Finalize(PCHECKSUM_BUFFER, PUCHAR); NTSTATUS NTAPI md4Finish(PCHECKSUM_BUFFER *); NTSTATUS NTAPI md5Initialize(ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI md5InitializeEx(PUCHAR, ULONG, ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI md5Sum(PCHECKSUM_BUFFER, ULONG, PUCHAR); NTSTATUS NTAPI md5Finalize(PCHECKSUM_BUFFER, PUCHAR); NTSTATUS NTAPI md5Finish(PCHECKSUM_BUFFER *); NTSTATUS NTAPI md25Initialize(ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI md25InitializeEx(PUCHAR, ULONG, ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI md25Sum(PCHECKSUM_BUFFER, ULONG, PUCHAR); NTSTATUS NTAPI md25Finalize(PCHECKSUM_BUFFER, PUCHAR); NTSTATUS NTAPI md25Finish(PCHECKSUM_BUFFER *); NTSTATUS NTAPI md5DesInitialize(ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI md5DesInitializeEx(PUCHAR, ULONG, ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI md5DesSum(PCHECKSUM_BUFFER, ULONG, PUCHAR); NTSTATUS NTAPI md5DesFinalize(PCHECKSUM_BUFFER, PUCHAR); NTSTATUS NTAPI md5DesFinish(PCHECKSUM_BUFFER *); NTSTATUS NTAPI md5Rc4Initialize(ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI md5Rc4InitializeEx(PUCHAR, ULONG, ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI md5Rc4Sum(PCHECKSUM_BUFFER, ULONG, PUCHAR); NTSTATUS NTAPI md5Rc4Finalize(PCHECKSUM_BUFFER, PUCHAR); NTSTATUS NTAPI md5Rc4Finish(PCHECKSUM_BUFFER *); NTSTATUS NTAPI md5HmacInitialize(ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI md5HmacInitializeEx(PUCHAR, ULONG, ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI md5Hmac2InitializeEx(PUCHAR, ULONG, ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI md5HmacSum(PCHECKSUM_BUFFER, ULONG, PUCHAR); NTSTATUS NTAPI md5HmacFinalize(PCHECKSUM_BUFFER, PUCHAR); NTSTATUS NTAPI md5HmacFinish(PCHECKSUM_BUFFER *); NTSTATUS NTAPI md5Des1510InitializeEx(PUCHAR, ULONG, ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI md5Des1510InitializeEx2(PUCHAR, ULONG, PUCHAR, ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI md5Des1510Finalize(PCHECKSUM_BUFFER, PUCHAR); NTSTATUS NTAPI md5Des1510Finish(PCHECKSUM_BUFFER *); #ifdef KERNEL_MODE #pragma alloc_text( PAGEMSG, md25Initialize ) #pragma alloc_text( PAGEMSG, md25InitializeEx ) #pragma alloc_text( PAGEMSG, md25Sum ) #pragma alloc_text( PAGEMSG, md25Finalize ) #pragma alloc_text( PAGEMSG, md25Finish ) #pragma alloc_text( PAGEMSG, md5DesInitialize ) #pragma alloc_text( PAGEMSG, md5DesInitializeEx ) #pragma alloc_text( PAGEMSG, md5DesSum ) #pragma alloc_text( PAGEMSG, md5DesFinalize ) #pragma alloc_text( PAGEMSG, md5DesFinish ) #pragma alloc_text( PAGEMSG, md5Rc4Initialize ) #pragma alloc_text( PAGEMSG, md5Rc4InitializeEx ) #pragma alloc_text( PAGEMSG, md5Rc4Sum ) #pragma alloc_text( PAGEMSG, md5Rc4Finalize ) #pragma alloc_text( PAGEMSG, md5Rc4Finish ) #pragma alloc_text( PAGEMSG, md5HmacInitialize ) #pragma alloc_text( PAGEMSG, md5HmacInitializeEx ) #pragma alloc_text( PAGEMSG, md5Hmac2InitializeEx ) #pragma alloc_text( PAGEMSG, md5HmacSum ) #pragma alloc_text( PAGEMSG, md5HmacFinalize ) #pragma alloc_text( PAGEMSG, md5HmacFinish ) #pragma alloc_text( PAGEMSG, md5Des1510InitializeEx ) #pragma alloc_text( PAGEMSG, md5Des1510InitializeEx2 ) #pragma alloc_text( PAGEMSG, md5Des1510Finalize ) #pragma alloc_text( PAGEMSG, md5Des1510Finish ) #endif CHECKSUM_FUNCTION csfMD4 = { KERB_CHECKSUM_MD4, // Checksum type MD4_LEN, // Checksum length 0, md4Initialize, md4Sum, md4Finalize, md4Finish, md4InitializeEx, NULL}; CHECKSUM_FUNCTION csfMD5 = { KERB_CHECKSUM_MD5, // Checksum type MD5_LEN, // Checksum length 0, md5Initialize, md5Sum, md5Finalize, md5Finish, md5InitializeEx, NULL}; CHECKSUM_FUNCTION csfMD25 = { KERB_CHECKSUM_MD25, // Checksum type (MD5_LEN / 2), // Checksum length CKSUM_KEYED, md25Initialize, md25Sum, md25Finalize, md25Finish, md25InitializeEx}; CHECKSUM_FUNCTION csfDES_MAC_MD5 = { KERB_CHECKSUM_DES_MAC_MD5, // Checksum type DES_BLOCKLEN, // Checksum length CKSUM_KEYED, md5DesInitialize, md5DesSum, md5DesFinalize, md5DesFinish, md5DesInitializeEx, NULL}; CHECKSUM_FUNCTION csfRC4_MD5 = { KERB_CHECKSUM_RC4_MD5, // Checksum type MD5_LEN, // Checksum length CKSUM_KEYED, md5Rc4Initialize, md5Rc4Sum, md5Rc4Finalize, md5Rc4Finish, md5Rc4InitializeEx, NULL}; CHECKSUM_FUNCTION csfMD5_HMAC = { KERB_CHECKSUM_MD5_HMAC, // Checksum type MD5_LEN, // Checksum length CKSUM_KEYED, md5HmacInitialize, md5HmacSum, md5HmacFinalize, md5HmacFinish, md5HmacInitializeEx, NULL}; CHECKSUM_FUNCTION csfHMAC_MD5 = { KERB_CHECKSUM_HMAC_MD5, // Checksum type MD5_LEN, // Checksum length CKSUM_KEYED, md5HmacInitialize, md5HmacSum, md5HmacFinalize, md5HmacFinish, md5Hmac2InitializeEx, NULL}; CHECKSUM_FUNCTION csfDES_MAC_MD5_1510 = { KERB_CHECKSUM_MD5_DES, // Checksum type DES_BLOCKLEN + MD5_LEN, // Checksum length CKSUM_KEYED, md5DesInitialize, md5DesSum, md5Des1510Finalize, md5Des1510Finish, md5Des1510InitializeEx, md5Des1510InitializeEx2}; /////////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI md4Initialize( ULONG dwSeed, PCHECKSUM_BUFFER * ppcsBuffer) { MD4_CTX * pMD4Context; #ifdef KERNEL_MODE pMD4Context = ExAllocatePool(NonPagedPool, sizeof(MD4_CTX)); #else pMD4Context = malloc(sizeof(MD4_CTX)); #endif if (!pMD4Context) { return(STATUS_NO_MEMORY); } MD4Init(pMD4Context); *ppcsBuffer = pMD4Context; return(STATUS_SUCCESS); } NTSTATUS NTAPI md4InitializeEx( PUCHAR Key, ULONG KeySize, ULONG MessageType, PCHECKSUM_BUFFER * ppcsBuffer ) { return(md4Initialize(0, ppcsBuffer)); } NTSTATUS NTAPI md4Sum( PCHECKSUM_BUFFER pcsBuffer, ULONG cbData, PUCHAR pbData) { MD4Update((MD4_CTX *) pcsBuffer, pbData, cbData); return(STATUS_SUCCESS); } NTSTATUS NTAPI md4Finalize( PCHECKSUM_BUFFER pcsBuffer, PUCHAR pbSum) { MD4Final((MD4_CTX *) pcsBuffer); memcpy(pbSum, ((MD4_CTX *) pcsBuffer)->digest, 16); return(STATUS_SUCCESS); } NTSTATUS NTAPI md4Finish( PCHECKSUM_BUFFER * ppcsBuffer) { #ifdef KERNEL_MODE ExFreePool(*ppcsBuffer); #else free(*ppcsBuffer); #endif *ppcsBuffer = 0; return(STATUS_SUCCESS); } /////////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI md5Initialize( ULONG dwSeed, PCHECKSUM_BUFFER * ppcsBuffer) { MD5_CTX * pMD5Context; #ifdef KERNEL_MODE pMD5Context = ExAllocatePool(NonPagedPool, sizeof(MD5_CTX)); #else pMD5Context = malloc(sizeof(MD5_CTX)); #endif if (!pMD5Context) { return(STATUS_NO_MEMORY); } MD5Init(pMD5Context); *ppcsBuffer = pMD5Context; return(STATUS_SUCCESS); } NTSTATUS NTAPI md5InitializeEx( PUCHAR Key, ULONG KeySize, ULONG MessageType, PCHECKSUM_BUFFER * ppcsBuffer) { return(md5Initialize(0, ppcsBuffer)); } NTSTATUS NTAPI md5Sum( PCHECKSUM_BUFFER pcsBuffer, ULONG cbData, PUCHAR pbData) { MD5Update((MD5_CTX *) pcsBuffer, pbData, cbData); return(STATUS_SUCCESS); } NTSTATUS NTAPI md5Finalize( PCHECKSUM_BUFFER pcsBuffer, PUCHAR pbSum) { MD5Final((MD5_CTX *) pcsBuffer); memcpy(pbSum, ((MD5_CTX *) pcsBuffer)->digest, 16); return(STATUS_SUCCESS); } NTSTATUS NTAPI md5Finish( PCHECKSUM_BUFFER * ppcsBuffer) { #ifdef KERNEL_MODE ExFreePool(*ppcsBuffer); #else free(*ppcsBuffer); #endif *ppcsBuffer = 0; return(STATUS_SUCCESS); } /////////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI desPlainInitialize(PUCHAR, ULONG, ULONG, PCRYPT_STATE_BUFFER *); NTSTATUS NTAPI desEncrypt(PCRYPT_STATE_BUFFER, PUCHAR, ULONG, PUCHAR, PULONG); NTSTATUS NTAPI desFinish(PCRYPT_STATE_BUFFER *); NTSTATUS NTAPI desMacInitialize(ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI desMacInitializeEx(PUCHAR,ULONG, ULONG, PCHECKSUM_BUFFER *); NTSTATUS NTAPI desMacSum(PCHECKSUM_BUFFER, ULONG, PUCHAR); NTSTATUS NTAPI desMacFinalize(PCHECKSUM_BUFFER, PUCHAR); NTSTATUS NTAPI desMacFinish(PCHECKSUM_BUFFER *); NTSTATUS NTAPI md25Initialize( ULONG dwSeed, PCHECKSUM_BUFFER * ppcsBuffer) { return(STATUS_NOT_IMPLEMENTED); } NTSTATUS NTAPI md25InitializeEx( PUCHAR Key, ULONG KeySize, ULONG MessageType, PCHECKSUM_BUFFER * ppcsBuffer) { MD5_CTX * pMD5Context; NTSTATUS Status = STATUS_SUCCESS; UCHAR TempBuffer[16]; ULONG OutputSize; UCHAR TempKey[DES_KEYSIZE]; PCRYPT_STATE_BUFFER DesContext = NULL; PCRYPTO_SYSTEM DesSystem; ULONG Index; memset( TempBuffer, 0, sizeof(TempBuffer) ); if (KeySize != DES_KEYSIZE) { return(STATUS_INVALID_PARAMETER); } #ifdef KERNEL_MODE pMD5Context = (MD5_CTX *) ExAllocatePool(NonPagedPool,sizeof(MD5_CTX)); #else pMD5Context = (MD5_CTX *) LocalAlloc(0,sizeof(MD5_CTX)); #endif if (!pMD5Context) { return(STATUS_INSUFFICIENT_RESOURCES); } MD5Init(pMD5Context); // // Prepare the key by byte reversing it. // for (Index = 0; Index < DES_KEYSIZE ; Index++ ) { TempKey[Index] = Key[(DES_KEYSIZE - 1) - Index]; } Status = CDLocateCSystem( KERB_ETYPE_DES_PLAIN, &DesSystem ); if (!NT_SUCCESS(Status)) { goto Cleanup; } Status = DesSystem->Initialize( TempKey, DES_KEYSIZE, 0, // no options &DesContext ); if (!NT_SUCCESS(Status)) { goto Cleanup; } Status = DesSystem->Encrypt( DesContext, TempBuffer, sizeof(TempBuffer), TempBuffer, &OutputSize ); ASSERT(OutputSize == sizeof(TempBuffer)); if (!NT_SUCCESS(Status)) { goto Cleanup; } (VOID) DesSystem->Discard(&DesContext); // // Now MD5 update with the encrypted buffer // MD5Update( pMD5Context, TempBuffer, sizeof(TempBuffer) ); *ppcsBuffer = (PCHECKSUM_BUFFER) pMD5Context; Cleanup: if (!NT_SUCCESS(Status) && (pMD5Context != NULL)) { #ifdef KERNEL_MODE ExFreePool(pMD5Context); #else LocalFree(pMD5Context); #endif } return(Status); } NTSTATUS NTAPI md25Sum( PCHECKSUM_BUFFER pcsBuffer, ULONG cbData, PUCHAR pbData) { MD5Update((MD5_CTX *) pcsBuffer, pbData, cbData); return(STATUS_SUCCESS); } NTSTATUS NTAPI md25Finalize( PCHECKSUM_BUFFER pcsBuffer, PUCHAR pbSum) { MD5Final((MD5_CTX *) pcsBuffer); memcpy(pbSum, ((MD5_CTX *) pcsBuffer)->digest, MD5_LEN/2); return(STATUS_SUCCESS); } NTSTATUS NTAPI md25Finish( PCHECKSUM_BUFFER * ppcsBuffer) { #ifdef KERNEL_MODE ExFreePool(*ppcsBuffer); #else LocalFree(*ppcsBuffer); #endif *ppcsBuffer = 0; return(STATUS_SUCCESS); } /////////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI md5DesInitialize( ULONG dwSeed, PCHECKSUM_BUFFER * ppcsBuffer) { return(STATUS_NOT_IMPLEMENTED); } NTSTATUS NTAPI md5DesInitializeEx( PUCHAR Key, ULONG KeySize, ULONG MessageType, PCHECKSUM_BUFFER * ppcsBuffer) { PMD5_DES_STATE_BUFFER pMD5Context; NTSTATUS Status = STATUS_SUCCESS; if (KeySize != DES_KEYSIZE) { return(STATUS_INVALID_PARAMETER); } #ifdef KERNEL_MODE pMD5Context = (PMD5_DES_STATE_BUFFER) ExAllocatePool(NonPagedPool,sizeof(MD5_DES_STATE_BUFFER)); #else pMD5Context = (PMD5_DES_STATE_BUFFER) LocalAlloc(0,sizeof(MD5_DES_STATE_BUFFER)); #endif if (!pMD5Context) { return(STATUS_INSUFFICIENT_RESOURCES); } MD5Init(&pMD5Context->Md5Context); // // Compute the initialization for the MD5 // Status = desPlainInitialize( Key, KeySize, 0, &pMD5Context->DesContext ); if (!NT_SUCCESS(Status)) { #ifdef KERNEL_MODE ExFreePool(pMD5Context); #else LocalFree(pMD5Context); #endif return(Status); } *ppcsBuffer = (PCHECKSUM_BUFFER) pMD5Context; return(STATUS_SUCCESS); } NTSTATUS NTAPI md5DesSum( PCHECKSUM_BUFFER pcsBuffer, ULONG cbData, PUCHAR pbData) { PMD5_DES_STATE_BUFFER Context = (PMD5_DES_STATE_BUFFER) pcsBuffer; MD5Update(&Context->Md5Context, pbData, cbData); return(STATUS_SUCCESS); } NTSTATUS NTAPI md5DesFinalize( PCHECKSUM_BUFFER pcsBuffer, PUCHAR pbSum) { ULONG OutputLength; PMD5_DES_STATE_BUFFER Context = (PMD5_DES_STATE_BUFFER) pcsBuffer; MD5Final(&Context->Md5Context); desEncrypt( Context->DesContext, Context->Md5Context.digest, MD5_LEN, Context->Md5Context.digest, &OutputLength ); RtlCopyMemory( pbSum, Context->Md5Context.digest + MD5_LEN-DES_BLOCKLEN, DES_BLOCKLEN ); return(STATUS_SUCCESS); } NTSTATUS NTAPI md5DesFinish( PCHECKSUM_BUFFER * ppcsBuffer) { PMD5_DES_STATE_BUFFER Context = (PMD5_DES_STATE_BUFFER) *ppcsBuffer; desFinish(&Context->DesContext); #ifdef KERNEL_MODE ExFreePool(Context); #else LocalFree(Context); #endif *ppcsBuffer = 0; return(STATUS_SUCCESS); } /////////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI rc4Md4Initialize(PUCHAR, ULONG, ULONG, PCRYPT_STATE_BUFFER *); NTSTATUS NTAPI rc4LmInitialize(PUCHAR, ULONG, ULONG, PCRYPT_STATE_BUFFER *); NTSTATUS NTAPI rc4ShaInitialize(PUCHAR, ULONG, ULONG, PCRYPT_STATE_BUFFER *); NTSTATUS NTAPI rc4Initialize(PUCHAR, ULONG, ULONG, ULONG, PCRYPT_STATE_BUFFER *); NTSTATUS NTAPI rc4Encrypt(PCRYPT_STATE_BUFFER, PUCHAR, ULONG, PUCHAR, PULONG); NTSTATUS NTAPI rc4Decrypt(PCRYPT_STATE_BUFFER, PUCHAR, ULONG, PUCHAR, PULONG); NTSTATUS NTAPI rc4Finish(PCRYPT_STATE_BUFFER *); NTSTATUS NTAPI md5Rc4Initialize( ULONG dwSeed, PCHECKSUM_BUFFER * ppcsBuffer) { return(STATUS_NOT_IMPLEMENTED); } NTSTATUS NTAPI md5Rc4InitializeEx( PUCHAR Key, ULONG KeySize, ULONG MessageType, PCHECKSUM_BUFFER * ppcsBuffer) { PMD5_DES_STATE_BUFFER pMD5Context; NTSTATUS Status = STATUS_SUCCESS; #ifdef KERNEL_MODE pMD5Context = (PMD5_DES_STATE_BUFFER) ExAllocatePool(NonPagedPool,sizeof(MD5_DES_STATE_BUFFER)); #else pMD5Context = (PMD5_DES_STATE_BUFFER) LocalAlloc(0,sizeof(MD5_DES_STATE_BUFFER)); #endif if (!pMD5Context) { return(STATUS_INSUFFICIENT_RESOURCES); } MD5Init(&pMD5Context->Md5Context); Status = rc4Initialize( Key, KeySize, 0, // no options 0, &pMD5Context->DesContext ); if (!NT_SUCCESS(Status)) { goto Cleanup; } if (!NT_SUCCESS(Status)) { #ifdef KERNEL_MODE ExFreePool(pMD5Context); #else LocalFree(pMD5Context); #endif return(Status); } *ppcsBuffer = (PCHECKSUM_BUFFER) pMD5Context; Cleanup: if (!NT_SUCCESS(Status) && (pMD5Context != NULL)) { #ifdef KERNEL_MODE ExFreePool(pMD5Context); #else LocalFree(pMD5Context); #endif } return(STATUS_SUCCESS); } NTSTATUS NTAPI md5Rc4Sum( PCHECKSUM_BUFFER pcsBuffer, ULONG cbData, PUCHAR pbData) { PMD5_DES_STATE_BUFFER Context = (PMD5_DES_STATE_BUFFER) pcsBuffer; MD5Update(&Context->Md5Context, pbData, cbData); return(STATUS_SUCCESS); } NTSTATUS NTAPI md5Rc4Finalize( PCHECKSUM_BUFFER pcsBuffer, PUCHAR pbSum) { PMD5_DES_STATE_BUFFER Context = (PMD5_DES_STATE_BUFFER) pcsBuffer; ULONG OutputSize; NTSTATUS Status; MD5Final(&Context->Md5Context); memcpy( pbSum, Context->Md5Context.digest, MD5_LEN ); Status = rc4Encrypt( Context->DesContext, pbSum, MD5_LEN, pbSum, &OutputSize ); ASSERT(OutputSize == MD5_LEN); if (!NT_SUCCESS(Status)) { return(Status); } return(STATUS_SUCCESS); } NTSTATUS NTAPI md5Rc4Finish( PCHECKSUM_BUFFER * ppcsBuffer) { PMD5_DES_STATE_BUFFER Context = (PMD5_DES_STATE_BUFFER) *ppcsBuffer; (VOID) rc4Finish(&Context->DesContext); #ifdef KERNEL_MODE ExFreePool(Context); #else LocalFree(Context); #endif *ppcsBuffer = 0; return(STATUS_SUCCESS); } /////////////////////////////////////////////////////////////////////////// BOOLEAN md5Hmac( IN PUCHAR pbKeyMaterial, IN ULONG cbKeyMaterial, IN PUCHAR pbData, IN ULONG cbData, IN PUCHAR pbData2, IN ULONG cbData2, OUT PUCHAR HmacData ); NTSTATUS NTAPI md5HmacInitialize( ULONG dwSeed, PCHECKSUM_BUFFER * ppcsBuffer) { return(STATUS_NOT_IMPLEMENTED); } NTSTATUS NTAPI md5HmacInitializeEx( PUCHAR Key, ULONG KeySize, ULONG MessageType, PCHECKSUM_BUFFER * ppcsBuffer) { PMD5_HMAC_STATE_BUFFER pMD5Context = NULL; NTSTATUS Status = STATUS_SUCCESS; #ifdef KERNEL_MODE pMD5Context = (PMD5_HMAC_STATE_BUFFER) ExAllocatePool(NonPagedPool,sizeof(MD5_HMAC_STATE_BUFFER) + KeySize); #else pMD5Context = (PMD5_HMAC_STATE_BUFFER) LocalAlloc(0,sizeof(MD5_HMAC_STATE_BUFFER) + KeySize); #endif if (!pMD5Context) { return(STATUS_INSUFFICIENT_RESOURCES); } RtlCopyMemory( pMD5Context->Key, Key, KeySize ); pMD5Context->KeySize = KeySize; MD5Init(&pMD5Context->Md5Context); MD5Update(&pMD5Context->Md5Context, (PUCHAR) &MessageType, sizeof(ULONG)); *ppcsBuffer = (PCHECKSUM_BUFFER) pMD5Context; return(STATUS_SUCCESS); } NTSTATUS NTAPI md5Hmac2InitializeEx( PUCHAR Key, ULONG KeySize, ULONG MessageType, PCHECKSUM_BUFFER * ppcsBuffer) { PMD5_HMAC_STATE_BUFFER pMD5Context = NULL; NTSTATUS Status = STATUS_SUCCESS; #ifdef KERNEL_MODE pMD5Context = (PMD5_HMAC_STATE_BUFFER) ExAllocatePool(NonPagedPool,sizeof(MD5_HMAC_STATE_BUFFER) + MD5_LEN); #else pMD5Context = (PMD5_HMAC_STATE_BUFFER) LocalAlloc(0,sizeof(MD5_HMAC_STATE_BUFFER) + MD5_LEN); #endif if (!pMD5Context) { return(STATUS_INSUFFICIENT_RESOURCES); } md5Hmac( Key, KeySize, "signaturekey", sizeof("signaturekey"), NULL, 0, pMD5Context->Key ); pMD5Context->KeySize = MD5_LEN; MD5Init(&pMD5Context->Md5Context); MD5Update(&pMD5Context->Md5Context, (PUCHAR) &MessageType, sizeof(ULONG)); *ppcsBuffer = (PCHECKSUM_BUFFER) pMD5Context; return(STATUS_SUCCESS); } NTSTATUS NTAPI md5HmacSum( PCHECKSUM_BUFFER pcsBuffer, ULONG cbData, PUCHAR pbData) { PMD5_HMAC_STATE_BUFFER Context = (PMD5_HMAC_STATE_BUFFER) pcsBuffer; MD5Update(&Context->Md5Context, pbData, cbData); return(STATUS_SUCCESS); } NTSTATUS NTAPI md5HmacFinalize( PCHECKSUM_BUFFER pcsBuffer, PUCHAR pbSum) { PMD5_HMAC_STATE_BUFFER Context = (PMD5_HMAC_STATE_BUFFER) pcsBuffer; MD5Final(&Context->Md5Context); if (!md5Hmac( Context->Key, Context->KeySize, Context->Md5Context.digest, MD5_LEN, NULL, // no secondary material 0, pbSum)) { return(STATUS_UNSUCCESSFUL); } return(STATUS_SUCCESS); } NTSTATUS NTAPI md5HmacFinish( PCHECKSUM_BUFFER * ppcsBuffer) { PMD5_HMAC_STATE_BUFFER Context = (PMD5_HMAC_STATE_BUFFER) *ppcsBuffer; #ifdef KERNEL_MODE ExFreePool(Context); #else LocalFree(Context); #endif *ppcsBuffer = 0; return(STATUS_SUCCESS); } NTSTATUS NTAPI md5Des1510InitializeEx( PUCHAR Key, ULONG KeySize, ULONG MessageType, PCHECKSUM_BUFFER * ppcsBuffer ) { return(STATUS_NOT_IMPLEMENTED); } NTSTATUS NTAPI md5Des1510InitializeEx2( PUCHAR Key, ULONG KeySize, PUCHAR ChecksumToVerify, ULONG MessageType, PCHECKSUM_BUFFER * ppcsBuffer ) { ULONG *pul; ULONG *pul2; UCHAR FinalKey[DES_KEYSIZE]; PMD5_DES_1510_STATE_BUFFER pContext = NULL; ULONG cb = DES_BLOCKLEN; NTSTATUS Status = STATUS_SUCCESS; // // Make sure we were passed an appropriate key // if (KeySize != DES_KEYSIZE) { Status = STATUS_INVALID_PARAMETER; goto Cleanup; } #ifdef KERNEL_MODE pContext = (PMD5_DES_1510_STATE_BUFFER) ExAllocatePool(NonPagedPool,sizeof(MD5_DES_1510_STATE_BUFFER)); #else pContext = (PMD5_DES_1510_STATE_BUFFER) LocalAlloc(0,sizeof(MD5_DES_1510_STATE_BUFFER)); #endif if (!pContext) { Status = STATUS_INSUFFICIENT_RESOURCES; goto Cleanup; } // // create the final key table // pul = (ULONG*)FinalKey; pul2 = (ULONG*)Key; *pul = *pul2 ^ 0xf0f0f0f0; pul = (ULONG*)(FinalKey + sizeof(ULONG)); pul2 = (ULONG*)(Key + sizeof(ULONG)); *pul = *pul2 ^ 0xf0f0f0f0; Status = desPlainInitialize( FinalKey, DES_KEYSIZE, 0, &pContext->DesContext ); if (!NT_SUCCESS(Status)) { goto Cleanup; } // // Checksum was not passed in so generate a confounder // if (NULL == ChecksumToVerify) { CDGenerateRandomBits(pContext->Confounder,DES_BLOCKLEN); } else { // the IV is all zero so no need to use CBC on first block Status = desEncrypt( pContext->DesContext, ChecksumToVerify, DES_BLOCKLEN, pContext->Confounder, &cb ); if (!NT_SUCCESS(Status)) { goto Cleanup; } } MD5Init(&pContext->Md5Context); // hash in the confounder MD5Update(&pContext->Md5Context, pContext->Confounder, DES_BLOCKLEN); *ppcsBuffer = (PCHECKSUM_BUFFER) pContext; Cleanup: if (Status != STATUS_SUCCESS) { if (NULL != pContext) { #ifdef KERNEL_MODE ExFreePool(pContext); #else LocalFree(pContext); #endif } } return(Status); } NTSTATUS NTAPI md5Des1510Finalize( PCHECKSUM_BUFFER pcsBuffer, PUCHAR pbSum) { UCHAR TmpBuffer[DES_BLOCKLEN * 2]; PMD5_DES_1510_STATE_BUFFER pContext = (PMD5_DES_1510_STATE_BUFFER) pcsBuffer; ULONG cb = DES_BLOCKLEN * 2; NTSTATUS Status = STATUS_SUCCESS; memcpy(TmpBuffer, pContext->Confounder, DES_BLOCKLEN); memcpy(TmpBuffer + DES_BLOCKLEN, pContext->Md5Context.digest, MD5_LEN); Status = desEncrypt( pContext->DesContext, TmpBuffer, DES_BLOCKLEN * 2, pbSum, &cb ); return(Status); } NTSTATUS NTAPI md5Des1510Finish( PCHECKSUM_BUFFER * ppcsBuffer) { PMD5_DES_1510_STATE_BUFFER pContext = (PMD5_DES_1510_STATE_BUFFER) *ppcsBuffer; desFinish(&pContext->DesContext); #ifdef KERNEL_MODE ExFreePool(pContext); #else LocalFree(pContext); #endif *ppcsBuffer = 0; return(STATUS_SUCCESS); }