📄 xtunnelscvsaes.cpp
字号:
/* File: XTunnelsCVsAES.cpp Contains: AES routines -- switched to MKS_AES implementation 03.11.07 Copyright: (c) 2003 by Xten Networks, Inc., all rights reserved.*/#include <iostream>#include <istream.h>#include <strstream>#include <algorithm>#include <string.h>#include "md5.h"#include "uuid.h"#include "XTunnelsCVsAES.h"#include "MKS_AES.h"#include "XTunnelsCVsSHA1.h"using std::string;using std::iostream;using std::istrstream;using std::ostrstream;using std::cout;using std::endl;using std::min;using std::max;using std::streamsize;typedef unsigned char uint8;typedef unsigned int uint32;class CVsInternalAES{public: PROCESS m_tCurrentEngineSetup; int m_iCurrentEngineBits; USERKEY m_tCurrentUserKey; CVsInternalAES() : m_tCurrentEngineSetup(nocrypt), m_iCurrentEngineBits(0) { bzero(&m_tCurrentUserKey, sizeof(m_tCurrentUserKey)); }/* AES key scheduling routine */ int aes_set_key(uint8 *key, int nbits ) { memcpy(&m_tCurrentUserKey, key, 32); if (nbits != m_iCurrentEngineBits) { aessetup(nbits); m_iCurrentEngineBits = nbits; m_tCurrentEngineSetup = nocrypt; bzero(&ukey, sizeof(ukey)); } return 0; // we could sanity check nbits to avoid exit() in aessetup }/* AES 128-bit block encryption routine */ void aes_encrypt(char data[16]) { if ((encrypt != m_tCurrentEngineSetup) || !memcmp(&ukey, &m_tCurrentUserKey, 32)) { memcpy(&ukey, &m_tCurrentUserKey, 32); aeskeyschedule(encrypt); } memcpy(&aesin, data, 16); aesprocess(); memcpy(data, &aesout, 16); }/* AES 128-bit block decryption routine */ void aes_decrypt(char data[16]) { if ((decrypt != m_tCurrentEngineSetup) || !memcmp(&ukey, &m_tCurrentUserKey, 32)) { memcpy(&ukey, &m_tCurrentUserKey, 32); aeskeyschedule(decrypt); } memcpy(&aesin, data, 16); aesprocess(); memcpy(data, &aesout, 16); }}; // class CVsInternalAESstruct STAESPrivateData{public: STAESPrivateData( const char * szKey, bool bEncrypt, unsigned long dwAESKeyLength ); ~STAESPrivateData();public: CVsInternalAES m_cAES; unsigned long m_dwLength; unsigned long m_dwBlockWidth; char m_pBuffer[24]; unsigned long m_dwFilledSize; bool m_bNextIoFails;};STAESPrivateData::STAESPrivateData( const char * szKey, bool bEncrypt, unsigned long dwAESKeyLength){#if VS_TARGET_OS_MAC#pragma unused (bEncrypt)#endif // VS_TARGET_OS_MAC m_bNextIoFails = false; const char * szAscIIKey = szKey; uuid_t tMD5DigestBytes; { struct MD5Context md5c; MD5Init(&md5c); MD5Update(&md5c, (const unsigned char *)szAscIIKey, strlen(szAscIIKey)*sizeof(char)); MD5Final((unsigned char*)&tMD5DigestBytes, &md5c); } CVsSHA1 cSHA1; cSHA1.Write((const BYTE *)szAscIIKey, strlen(szAscIIKey)*sizeof(char)); cSHA1.Close(); m_dwFilledSize = 0; bzero(m_pBuffer, sizeof(m_pBuffer)); m_dwLength = dwAESKeyLength; m_dwBlockWidth = sizeof(BYTE)*16; BYTE *pHashKey = new BYTE[cSHA1.GetDigestBytesLength() + sizeof(tMD5DigestBytes) + sizeof(char)]; if (NULL == pHashKey) return; bzero(pHashKey, cSHA1.GetDigestBytesLength() + sizeof(tMD5DigestBytes) + sizeof(char)); memcpy(pHashKey, cSHA1.GetDigestBytes(), cSHA1.GetDigestBytesLength()); memcpy(pHashKey + cSHA1.GetDigestBytesLength(), &tMD5DigestBytes, sizeof(tMD5DigestBytes)); m_cAES.aes_set_key(&(pHashKey[0]), dwAESKeyLength);}STAESPrivateData::~STAESPrivateData(){}void CVsAES::Init(){ m_pData = NULL; m_iStream = NULL; m_oStream = NULL;}void CVsAES::Destroy(){ Close();}void CVsAES::OpenRead( const char * szKey, istrstream *ipInputStream, CVsAES::AESKeyLength eKeyLength){ Close(); if (NULL == ipInputStream) return; m_pData = new STAESPrivateData( szKey, false, (unsigned long)eKeyLength ); if (NULL == m_pData) return; m_iStream = ipInputStream; m_bReadMode = true;}void CVsAES::OpenWrite( const char * szKey, ostrstream *ipOuputStream, CVsAES::AESKeyLength eKeyLength){ Close(); if (NULL == ipOuputStream) return; m_pData = new STAESPrivateData( szKey, true, (unsigned long)eKeyLength ); if (NULL == m_pData) return; m_oStream = ipOuputStream; m_bReadMode = false;}bool CVsAES::Read( char *pBuffer, unsigned long dwBytesToRead, unsigned long *pBytesRead){ bool bReturnResult = false; unsigned long dwTotalBytesRead = 0; if (NULL == m_pData) return bReturnResult; if (NULL == m_iStream) return bReturnResult; if (!m_bReadMode) return bReturnResult; if (0 == dwBytesToRead) goto NEXT; while (0 != dwBytesToRead) { // still some stuff in the buffer from the last read while ((m_pData->m_dwFilledSize > 0) && (0 != dwBytesToRead)) { unsigned long dwReadSize = min<unsigned long>(dwBytesToRead, m_pData->m_dwFilledSize); // okay lets reads what's left in the buffer memcpy(pBuffer, m_pData->m_pBuffer, dwReadSize); pBuffer += dwReadSize; dwTotalBytesRead += dwReadSize; m_pData->m_dwFilledSize -= dwReadSize; if (m_pData->m_dwFilledSize < m_pData->m_dwBlockWidth) { // move any unread data in buffer over now... memcpy( m_pData->m_pBuffer, &(m_pData->m_pBuffer[dwReadSize]), m_pData->m_dwFilledSize ); } // decrease amount of buffer left in stream dwBytesToRead -= dwReadSize; } if (0 == dwBytesToRead) goto NEXT; if ((0 == dwTotalBytesRead) && (m_pData->m_bNextIoFails)) return bReturnResult; if (m_pData->m_bNextIoFails) goto NEXT; // fill the entire buffer all over again while (m_pData->m_dwFilledSize < m_pData->m_dwBlockWidth) { unsigned long dwActualBytesRead = 0; bool bResult = false; streamsize tAvailable = m_iStream->rdbuf()->in_avail(); if (tAvailable > 0) { streamsize tToRead = m_pData->m_dwBlockWidth - m_pData->m_dwFilledSize; tToRead = min<streamsize>(tToRead, tAvailable); m_iStream->read( &(m_pData->m_pBuffer[m_pData->m_dwFilledSize]), tToRead ); if (m_iStream->good()) { bResult = true; dwActualBytesRead = tToRead; m_pData->m_dwFilledSize += dwActualBytesRead; }#if DEBUG else cout << "WARNING: CVsAES::Read(): m_iStream->good() failed!" << endl;#endif // DEBUG } // zero out the rest of the buffer memset(&m_pData->m_pBuffer[m_pData->m_dwFilledSize], 0, m_pData->m_dwBlockWidth - m_pData->m_dwFilledSize); // the next read should fail as well if (!bResult) { m_pData->m_bNextIoFails = true; if ((0 == dwTotalBytesRead) && (0 == m_pData->m_dwFilledSize)) goto FINALLY; // this write fails NOW! else { if (0 == m_pData->m_dwFilledSize) goto NEXT; // no more data in AES buffer, but some data was read, next read will fail break; // some stuff in AES buffer, decrypt, next read will fail } } if ((0 == dwActualBytesRead) && (0 == m_pData->m_dwFilledSize)) goto NEXT; // at end of file if (0 == dwActualBytesRead) // at end of file, but stuff in AES buffer, decrypt break; } m_pData->m_cAES.aes_decrypt(m_pData->m_pBuffer); }} NEXT: { if (NULL != pBytesRead) *pBytesRead = dwTotalBytesRead; bReturnResult = true; } FINALLY: { } return bReturnResult;}bool CVsAES::Write( const char *pBuffer, unsigned long dwBufferLength, unsigned long *pBytesWritten){ bool bReturnResult = false; if (NULL == m_pData) return bReturnResult; if (NULL == m_oStream) return bReturnResult; if (m_bReadMode) return bReturnResult; if (m_pData->m_bNextIoFails) return bReturnResult; // keep writting while there is more buffer to write while (dwBufferLength > 0) { // fill the AES buffer to max capacity unsigned long dwFillAmount = min<unsigned long>(dwBufferLength, m_pData->m_dwBlockWidth - m_pData->m_dwFilledSize); memcpy(&(m_pData->m_pBuffer[m_pData->m_dwFilledSize]), pBuffer, dwFillAmount); pBuffer += dwFillAmount; dwBufferLength -= dwFillAmount; m_pData->m_dwFilledSize += dwFillAmount; if (m_pData->m_dwFilledSize < m_pData->m_dwBlockWidth) goto NEXT; // not enough data to fill the entire buffer with, wait until next fill // encrypt the data now m_pData->m_cAES.aes_encrypt(m_pData->m_pBuffer); // keep trying to output the buffer into the output stream while (m_pData->m_dwFilledSize > 0) { unsigned long dwActualBytesWritten = 0; dwActualBytesWritten = m_pData->m_dwFilledSize; bool bResult = NULL != m_oStream->write(m_pData->m_pBuffer, dwActualBytesWritten); if (pBytesWritten) *pBytesWritten += dwActualBytesWritten; if ((!bResult) || (0 == dwActualBytesWritten)) { m_pData->m_bNextIoFails = true; goto FINALLY; } m_pData->m_dwFilledSize -= dwActualBytesWritten; if (0 != m_pData->m_dwFilledSize) { // shift the buffer over memcpy(m_pData->m_pBuffer, &(m_pData->m_pBuffer[dwActualBytesWritten]), m_pData->m_dwFilledSize); } } }} NEXT: { bReturnResult = true; } FINALLY: { } return bReturnResult;}void CVsAES::Close(unsigned long *pBytesWritten){ if (NULL != m_pData) { if (!m_bReadMode) { if (!m_pData->m_bNextIoFails) { // still some data left in AES buffer to write? if (m_pData->m_dwFilledSize > 0) { // zero out any left over bits... memset(&(m_pData->m_pBuffer[m_pData->m_dwFilledSize]), 0, m_pData->m_dwBlockWidth - m_pData->m_dwFilledSize); m_pData->m_dwFilledSize += (m_pData->m_dwBlockWidth - m_pData->m_dwFilledSize); // encrypt the data now m_pData->m_cAES.aes_encrypt(m_pData->m_pBuffer); // keep trying to output the buffer into the output stream while (m_pData->m_dwFilledSize > 0) { unsigned long dwActualBytesWritten = 0; dwActualBytesWritten = m_pData->m_dwFilledSize; bool bResult = NULL != m_oStream->write(m_pData->m_pBuffer, dwActualBytesWritten); if (pBytesWritten) *pBytesWritten += dwActualBytesWritten; if ((!bResult) || (0 == dwActualBytesWritten)) { break; // ohh well... } m_pData->m_dwFilledSize -= dwActualBytesWritten; if (0 != m_pData->m_dwFilledSize) { // shift the buffer over memcpy(m_pData->m_pBuffer, &(m_pData->m_pBuffer[dwActualBytesWritten]), m_pData->m_dwFilledSize); } } } } } delete m_pData; m_pData = NULL; } m_oStream = NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -