Mixe for Privacy and Anonymity in the Internet
CADataRetentionLogFile.cpp
Go to the documentation of this file.
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