/// hdrutil.h // Macros and types to support encode/decode of linearized headers #ifndef _LHUTIL_H #define _LHUTIL_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include /////////////////////////////////////////////////////////////////////////// /// Extern variables /// // DEBUG #ifdef DEBUG extern DBGPARAM dpCurSettings; #define ZONE_LINEARIZER (0x0001 & dpCurSettings.ulZoneMask) #define ZONE_LIN_VERBOSE (0x0002 & dpCurSettings.ulZoneMask) extern WORD wHashSize; #endif /////////////////////////////////////////////////////////////////////////// /// Errors /// #ifndef NO_ERROR # define NO_ERROR (0) #endif #define ERR_MEMORY_ERROR (1) #define ERR_INVALID_OCTETS (2) #define ERR_UNEXPECTED_OCTETS (3) #define ERR_UNEXPECTED_LENGTH (4) #define ERR_DATASTREAM_ERROR (5) // Define this small because we only use it on the header !! #define MAX_OCTETBLOCK_SIZE 256 /////////////////////////////////////////////////////////////////////////// /// Types /// typedef unsigned char OCTET; typedef DWORD OCTETSINK; typedef DWORD OCTETSOURCE; typedef DWORD OCTETFILE; typedef struct _LININST { DWORD octets; // Source/sink for linearized format. This // is used to get at all the data. DWORD dwGlobalError; // Error for this job LPDATACB lpfnData; // Callback to read/write source/sink DWORD dwHashInstance; // Hashing instance ... BYTE rgb[MAX_OCTETBLOCK_SIZE]; // For decoding memory ... } LININST, FAR *LPLININST, NEAR *NPLININST; //------------------------------------------------------------------------ // This def relies on the fact that there is a variable called // lininst in the calling function which pts to the instance #define AllocLinMemMacro(lpRet, uSize) lpRet = lplinst->rgb; // Nothing to do since its in the instance #define FreeLinMemMacro(lpVal) (VOID)(0) #define OctetInMacro(lplinst, pOctet) OctetDataMacro(GPM_GETDATA, lplinst, (LPBYTE)pOctet, 1) #define OctetOutMacro(lplinst, Octet) \ { \ OCTET oct = Octet; \ OctetDataMacro(GPM_PUTDATA, lplinst, (LPBYTE)&oct, 1); \ } #define OctetBlockInMacro(lplinst, lpb, size) OctetDataMacro(GPM_GETDATA, lplinst, lpb, size) #define OctetBlockOutMacro(lplinst, lpb, size) OctetDataMacro(GPM_PUTDATA, lplinst, lpb, size) #define OctetDataMacro(gpm, lplinst, lpb, size) \ do { \ if ((*lplinst->lpfnData)(gpm, lplinst->octets, (LPBYTE)(lpb), size, NULL)!=size) \ { \ DEBUGMSG(1, (THIS_FUNCTION ":Octet read/write Failed !!\r\n")); \ lplinst->dwGlobalError = ERR_DATASTREAM_ERROR; \ goto error; \ } \ /* Hash it if necessary */ \ if (lplinst->dwHashInstance) \ { \ DEBUGSTMT(wHashSize+=size); \ DEBUGCHK(size <= 0xffff); \ SendBFTHash(lplinst->dwHashInstance, (LPBYTE)(lpb), (WORD)size); \ } \ } \ while (0) /// Utility functions to encode / decode a header #define WriteHdrOpen(lplinst) \ { \ OctetOutMacro(lplinst, TAG_MESSAGE_HEADER); \ ASN1EncodeIndefiniteLengthMacro(lplinst); \ } #define WriteHdrClose(lplinst) \ { \ ASN1EncodeEndOfContentsOctetsMacro(lplinst); \ WriteHashMacro(lplinst); \ } #define WriteOrigOpen(lplinst) \ OctetOutMacro (lplinst, TAG_FROM); \ ASN1EncodeIndefiniteLengthMacro(lplinst); \ OctetOutMacro (lplinst, TAG_RECIP_DESC); \ ASN1EncodeIndefiniteLengthMacro(lplinst); #define WriteOrigClose(lplinst) \ ASN1EncodeEndOfContentsOctetsMacro(lplinst); \ ASN1EncodeEndOfContentsOctetsMacro(lplinst); #define WriteRecipOpen(lplinst) \ OctetOutMacro (lplinst, TAG_TO); \ ASN1EncodeIndefiniteLengthMacro(lplinst); \ OctetOutMacro (lplinst, TAG_RECIP_DESC); \ ASN1EncodeIndefiniteLengthMacro(lplinst); #define WriteRecipClose(lplinst) WriteOrigClose(lplinst) #define WriteString(lplinst, tag, string) \ ASN1EncodePrimitiveStringImplicitMacro(lplinst, tag, string, lstrlen(string)+1) // Hashing macros #define StartHashMacro(lplinst) \ { \ if (!(lplinst->dwHashInstance = StartBFTHash())) \ { \ DEBUGMSG(1, (THIS_FUNCTION ":Error getting hash instance!\n\r")); \ lplinst->dwGlobalError = ERR_NOMEMORY; \ goto error; \ } \ DEBUGSTMT(wHashSize=0); \ } #define WriteHashMacro(lplinst) \ { \ BYTE bHash[16]; \ BYTE bSalt[3]; \ _fmemset(bHash, 0, sizeof(bHash)); \ _fmemset(bSalt, 0, sizeof(bSalt)); \ /* Complete the hash if we initialized it */ \ if (lplinst->dwHashInstance) \ { \ DoneBFTHash(lplinst->dwHashInstance, bSalt, bHash); \ lplinst->dwHashInstance = 0; \ } \ OctetBlockOutMacro(lplinst, bSalt, sizeof(bSalt)); \ OctetBlockOutMacro(lplinst, bHash, sizeof(bHash)); \ DEBUGMSG(ZONE_LINEARIZER, ("Lhutil: Hdr Hash Size %u\r\n", wHashSize)); \ } #define CheckHashMacro(lplinst) \ { \ BYTE rgbMsgHash[19], rgbNewHash[16]; \ DWORD dwInstance = lplinst->dwHashInstance; \ /* Reset instance so we dont hash the msg hash */ \ lplinst->dwHashInstance = 0; \ OctetBlockInMacro(lplinst, rgbMsgHash, sizeof(rgbMsgHash)); \ /* Generate current hash using same salt */ \ DoneBFTHash(dwInstance, rgbMsgHash, rgbNewHash); \ /* Compare them */ \ if (! BinComp(sizeof(rgbNewHash), rgbMsgHash+3, \ sizeof(rgbNewHash), rgbNewHash) != 0) \ { \ DEBUGMSG(1, ("ERROR: Hash Does not match !!!\n\r")); \ lplinst->dwGlobalError = ERR_GENERAL_FAILURE; \ goto error; \ } \ } /////////////////////////////////////////////////////////////////////////// /// Internal funcion prototypes /// BOOL __fastcall BinComp(DWORD cbA, PVOID lpA, DWORD cbB, PVOID lpB); #ifdef __cplusplus } // extern "C" #endif #endif // hdrutil_inc