|
Mixe for Privacy and Anonymity in the Internet
|
00001 #include "StdAfx.h" 00002 #ifdef DATA_RETENTION_LOG 00003 #include "CADataRetentionLogFile.hpp" 00004 #include "CAMsg.hpp" 00005 #include "CACmdLnOptions.hpp" 00006 #include "CALibProxytest.hpp" 00007 CADataRetentionLogFile::CADataRetentionLogFile() 00008 { 00009 m_nCurrentLogEntriesInBlock=0; 00010 m_hLogFile=-1; 00011 m_nBytesPerLogEntry=sizeof(t_dataretentionLogEntry); 00012 m_nLogEntriesPerBlock=128; 00013 m_arOneBlock=new UINT8[m_nLogEntriesPerBlock*m_nBytesPerLogEntry]; 00014 m_encBlock=new UINT8[m_nLogEntriesPerBlock*m_nBytesPerLogEntry+1024]; 00015 m_pGCMCtx=new gcm_ctx_64k; 00016 m_nonceBuffForLogEntries=new UINT8[12]; 00017 } 00018 00019 CADataRetentionLogFile::~CADataRetentionLogFile() 00020 { 00021 closeLog(); 00022 } 00023 00024 SINT32 CADataRetentionLogFile::openLog(UINT8* strLogDir,UINT32 date,CAASymCipher* pPublicKey) 00025 { 00026 m_nCurrentLogEntriesInBlock=0; 00027 m_nCurrentBlockNumber=0; 00028 UINT8* strFileName=new UINT8[4096]; 00029 UINT8 strDate[256]; 00030 struct tm* theTime; 00031 time_t t=date; 00032 theTime=gmtime(&t); 00033 strftime((char*) strDate,255,"%Y%m%d-%H%M%S",theTime); 00034 m_Day=theTime->tm_mday; 00035 m_Month=theTime->tm_mon+1; 00036 m_Year=theTime->tm_year+1900; 00037 00038 m_nMaxLogTime=date-theTime->tm_min*60-theTime->tm_hour*3600-theTime->tm_sec+24*3600-1; 00039 00040 // m_nMaxLogTime=date+60; 00041 00042 snprintf((char*)strFileName,4096,"%s/dataretentionlog_%s",strLogDir,strDate); 00044 m_hLogFile=open((char*)strFileName,O_APPEND|O_CREAT|O_WRONLY|O_LARGEFILE|O_BINARY,S_IREAD|S_IWRITE); 00045 delete [] strFileName; 00046 if(m_hLogFile<=0) 00047 return E_UNKNOWN; 00048 return writeHeader(pPublicKey); 00049 } 00050 00051 SINT32 CADataRetentionLogFile::writeHeader(CAASymCipher* pPublicKey) 00052 { 00053 t_dataretentionLogFileHeader oHeader; 00054 memset(&oHeader,0,sizeof(oHeader)); 00055 oHeader.day=m_Day; 00056 oHeader.month=m_Month; 00057 oHeader.year=htons(m_Year); 00058 oHeader.entriesPerBlock=m_nLogEntriesPerBlock; 00059 oHeader.keys=1; 00060 oHeader.loggedFields=0x00FF;//DATARETETION_LOGGED_FIELD_T_IN|DATARETETION_LOGGED_FIELD_T_OUT 00061 if(CALibProxytest::getOptions()->isFirstMix()) 00062 { 00063 oHeader.entity=DATARETENTION_ENTITY_FIRST_MIX; 00064 } 00065 else if(CALibProxytest::getOptions()->isMiddleMix()) 00066 { 00067 oHeader.entity=DATARETENTION_ENTITY_MIDDLE_MIX; 00068 } 00069 else if(CALibProxytest::getOptions()->isLastMix()) 00070 { 00071 oHeader.entity=DATARETENTION_ENTITY_LAST_MIX; 00072 } 00073 if(write(m_hLogFile,&oHeader,sizeof(oHeader))!=sizeof(oHeader)) 00074 return E_UNKNOWN; 00075 00076 //Generate sym key and write it to header 00077 UINT8 keybuff[256]; 00078 getRandom(keybuff,16); 00079 gcm_init_64k(m_pGCMCtx,keybuff,128); 00080 UINT8 encKey[2048]; 00081 UINT32 encKeyLen=2048; 00082 //Set date 00083 keybuff[16]=m_Day; 00084 keybuff[17]=m_Month; 00085 keybuff[18]=m_Year>>8; 00086 keybuff[19]=(m_Year&0x00FF); 00087 //Calculate MAC 00088 UINT8 nonce[12]; 00089 memset(nonce,0xFF,11); 00090 nonce[11]=0xFE; 00091 ::gcm_encrypt_64k(m_pGCMCtx, nonce, 12, keybuff,20, 00092 NULL,0,encKey,keybuff+20); 00093 00094 encKeyLen=256; 00095 pPublicKey->encryptPKCS1(keybuff,36,encKey,&encKeyLen); 00096 00097 //Calculate the symmetric key 00098 UINT8 md[SHA512_DIGEST_LENGTH]; 00099 SHA512(keybuff+16,4,md); 00100 for(UINT32 i=0;i<16;i++) 00101 { 00102 keybuff[i]^=md[i]; 00103 } 00104 gcm_destroy_64k(m_pGCMCtx); 00105 gcm_init_64k(m_pGCMCtx,keybuff,128); 00106 00107 memset(keybuff,0,256); 00108 00109 if(write(m_hLogFile,encKey,encKeyLen)!=encKeyLen) 00110 return E_UNKNOWN; 00111 00112 //Calculate Auth tag and writ it.. 00113 UINT8 tmpBuff[2048]; 00114 nonce[11]=0xFD; 00115 memcpy(tmpBuff,&oHeader,sizeof(oHeader)); 00116 memcpy(tmpBuff+sizeof(oHeader),encKey,encKeyLen); 00117 ::gcm_encrypt_64k(m_pGCMCtx, nonce, 12, tmpBuff,sizeof(oHeader)+encKeyLen, 00118 NULL,0,tmpBuff+1024,keybuff); 00119 00120 if(write(m_hLogFile,keybuff,16)!=16) 00121 return E_UNKNOWN; 00122 00123 memset(m_nonceBuffForLogEntries,0,12); 00124 00125 00126 return E_SUCCESS; 00127 } 00128 00129 SINT32 CADataRetentionLogFile::flushLogEntries() 00130 { 00131 if(m_nCurrentLogEntriesInBlock>0) 00132 {//Writte remaining log entries 00133 UINT32 nonce=htonl(m_nCurrentBlockNumber); 00134 memcpy(m_nonceBuffForLogEntries+8,&nonce,4); 00135 ::gcm_encrypt_64k(m_pGCMCtx, m_nonceBuffForLogEntries ,12, m_arOneBlock,m_nCurrentLogEntriesInBlock*m_nBytesPerLogEntry, 00136 NULL,0,m_encBlock,m_encBlock+m_nCurrentLogEntriesInBlock*m_nBytesPerLogEntry); 00137 if(write(m_hLogFile,m_encBlock,m_nCurrentLogEntriesInBlock*m_nBytesPerLogEntry+16)!=m_nCurrentLogEntriesInBlock*m_nBytesPerLogEntry+16) 00138 { 00139 CAMsg::printMsg(LOG_ERR,"Error: data retention log entry was not fully written to disk!\n"); 00140 return E_UNKNOWN; 00141 } 00142 } 00143 return E_SUCCESS; 00144 } 00145 00146 SINT32 CADataRetentionLogFile::writeFooter() 00147 { 00148 SINT32 ret=flushLogEntries(); 00149 if(ret!=E_SUCCESS) 00150 return E_UNKNOWN; 00151 UINT32 u=htonl(m_nCurrentLogEntriesInBlock+m_nCurrentBlockNumber*m_nLogEntriesPerBlock); 00152 UINT8 out[32]; 00153 UINT8 nonce[12]; 00154 memset(nonce,0xFF,12); 00155 ::gcm_encrypt_64k(m_pGCMCtx, nonce ,12,(UINT8*) &u,4, 00156 NULL,0,out,out+4); 00157 if(write(m_hLogFile,out,20)!=20) 00158 return E_UNKNOWN; 00159 return E_SUCCESS; 00160 } 00161 00162 SINT32 CADataRetentionLogFile::closeLog() 00163 { 00164 if(m_hLogFile==-1) 00165 return E_SUCCESS; 00166 SINT32 ret=writeFooter(); 00167 if(ret!=E_SUCCESS) 00168 return ret; 00169 ret=close(m_hLogFile); 00170 m_hLogFile=-1; 00171 if(ret==0) 00172 return E_SUCCESS; 00173 return E_UNKNOWN; 00174 } 00175 00176 SINT32 CADataRetentionLogFile::log(t_dataretentionLogEntry* logEntry) 00177 { 00178 SINT32 ret=E_SUCCESS; 00179 memcpy(m_arOneBlock+m_nBytesPerLogEntry*m_nCurrentLogEntriesInBlock,logEntry,m_nBytesPerLogEntry); 00180 m_nCurrentLogEntriesInBlock++; 00181 00182 if(m_nCurrentLogEntriesInBlock>=m_nLogEntriesPerBlock) 00183 {//Block is full -->encrypt and write them 00184 UINT32 nonce=htonl(m_nCurrentBlockNumber); 00185 memcpy(m_nonceBuffForLogEntries+8,&nonce,4); 00186 ::gcm_encrypt_64k(m_pGCMCtx, m_nonceBuffForLogEntries ,12, m_arOneBlock,m_nLogEntriesPerBlock*m_nBytesPerLogEntry, 00187 NULL,0,m_encBlock,m_encBlock+m_nLogEntriesPerBlock*m_nBytesPerLogEntry); 00188 if(write(m_hLogFile,m_encBlock,m_nLogEntriesPerBlock*m_nBytesPerLogEntry+16)!=m_nLogEntriesPerBlock*m_nBytesPerLogEntry+16) 00189 { 00190 CAMsg::printMsg(LOG_ERR,"Error: data retention log entry was not fully written to disk!\n"); 00191 ret=E_UNKNOWN; 00192 } 00193 m_nCurrentLogEntriesInBlock=0; 00194 m_nCurrentBlockNumber++; 00195 } 00196 return ret; 00197 } 00198 00199 SINT32 CADataRetentionLogFile::doCheckAndPerformanceTest() 00200 { 00201 UINT8 keybuff[256]; 00202 UINT8 tag[128]; 00203 UINT8 nonce[12]; 00204 memset(nonce,0xFF,12); 00205 UINT8 oneBlock[8192]; 00206 memset(oneBlock,0xd4,8192); 00207 UINT8 encBlock[10000]; 00208 memset(keybuff,0xC1,16); 00209 UINT32 lenBlock=64; 00210 UINT64 start; 00211 const UINT32 runs=100000; 00212 gcm_ctx_4k* pGCMCtx=new gcm_ctx_4k; 00213 00214 for(int l=0;l<7;l++) 00215 { 00216 gcm_init_4k(pGCMCtx,keybuff,128); 00217 getcurrentTimeMillis(start); 00218 for(UINT32 i =0;i<runs;i++) 00219 ::gcm_encrypt_4k(pGCMCtx, nonce ,12, oneBlock,lenBlock,NULL,0,encBlock,tag); 00220 UINT64 end; 00221 getcurrentTimeMillis(end); 00222 print64(encBlock,diff64(end,start)); 00223 double bytes=(double)(runs*lenBlock); 00224 double thetime=(double)diff64(end,start); 00225 printf("Time for %u run of 4k encypt of %u bytes: %s [ms] (%f bytes/s)\n",runs,lenBlock,encBlock,bytes/thetime*1000.0); 00226 lenBlock<<=1; 00227 } 00228 gcm_ctx_64k* pGCMCtx64=new gcm_ctx_64k; 00229 lenBlock=64; 00230 UINT8 tmpBlock[8192]; 00231 00232 for(int l=0;l<7;l++) 00233 { 00234 gcm_init_64k(pGCMCtx64,keybuff,128); 00235 getcurrentTimeMillis(start); 00236 for(UINT32 i =0;i<runs;i++) 00237 ::gcm_encrypt_64k(pGCMCtx64, nonce ,12, oneBlock,lenBlock,NULL,0,encBlock,tag); 00238 UINT64 end; 00239 getcurrentTimeMillis(end); 00240 print64(tmpBlock,diff64(end,start)); 00241 double bytes=(double)(runs*lenBlock); 00242 double thetime=(double)diff64(end,start); 00243 printf("Time for %u run of 64k encypt of %u bytes: %s [ms] (%f bytes/s)\n",runs,lenBlock,tmpBlock,bytes/thetime*1000.0); 00244 lenBlock<<=1; 00245 } 00246 lenBlock>>=1; 00247 printf("Test finished!\n"); 00248 00249 memset(tmpBlock,1,8192); 00250 if(gcm_decrypt_4k(pGCMCtx,nonce,12,encBlock,lenBlock,tag,16,NULL,0,tmpBlock)==0||memcmp(oneBlock,tmpBlock,lenBlock)!=0) 00251 printf("Check failed!\n"); 00252 else 00253 printf("Check success!\n"); 00254 00255 printf("Check finished!\n"); 00256 return E_SUCCESS; 00257 } 00258 00259 #endif //DATA_RETENTION_LOG
1.7.6.1