|
Mixe for Privacy and Anonymity in the Internet
|
00001 /* 00002 Copyright (c) 2000, The JAP-Team 00003 All rights reserved. 00004 Redistribution and use in source and binary forms, with or without modification, 00005 are permitted provided that the following conditions are met: 00006 00007 - Redistributions of source code must retain the above copyright notice, 00008 this list of conditions and the following disclaimer. 00009 00010 - Redistributions in binary form must reproduce the above copyright notice, 00011 this list of conditions and the following disclaimer in the documentation and/or 00012 other materials provided with the distribution. 00013 00014 - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors 00015 may be used to endorse or promote products derived from this software without specific 00016 prior written permission. 00017 00018 00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 00027 */ 00028 #include "StdAfx.h" 00029 #include "CASymCipher.hpp" 00030 //AES 00031 00036 SINT32 CASymCipher::setKey(const UINT8* key) 00037 { 00038 return setKey(key,true); 00039 } 00040 00046 SINT32 CASymCipher::setKey(const UINT8* key,bool bEncrypt) 00047 { 00048 #ifdef INTEL_IPP_CRYPTO 00049 ippsRijndael128Init(key, IppsRijndaelKey128,m_keyAES1); 00050 ippsRijndael128Init(key, IppsRijndaelKey128,m_keyAES2); 00051 #else 00052 if(bEncrypt) 00053 { 00054 AES_set_encrypt_key(key,128,m_keyAES1); 00055 AES_set_encrypt_key(key,128,m_keyAES2); 00056 } 00057 else 00058 { 00059 AES_set_decrypt_key(key,128,m_keyAES1); 00060 AES_set_decrypt_key(key,128,m_keyAES2); 00061 } 00062 #endif 00063 memset(m_iv1,0,16); 00064 memset(m_iv2,0,16); 00065 m_bKeySet=true; 00066 return E_SUCCESS; 00067 } 00068 00069 SINT32 CASymCipher::setKeys(const UINT8* key,UINT32 keysize) 00070 { 00071 if(keysize==KEY_SIZE) 00072 { 00073 return setKey(key); 00074 } 00075 else if(keysize==2*KEY_SIZE) 00076 { 00077 #ifdef INTEL_IPP_CRYPTO 00078 ippsRijndael128Init(key, IppsRijndaelKey128,m_keyAES1); 00079 ippsRijndael128Init(key+KEY_SIZE, IppsRijndaelKey128,m_keyAES2); 00080 #else 00081 AES_set_encrypt_key(key,128,m_keyAES1); 00082 AES_set_encrypt_key(key+KEY_SIZE,128,m_keyAES2); 00083 #endif 00084 memset(m_iv1,0,16); 00085 memset(m_iv2,0,16); 00086 m_bKeySet=true; 00087 return E_SUCCESS; 00088 } 00089 return E_UNKNOWN; 00090 } 00091 00104 SINT32 CASymCipher::crypt1(const UINT8* in,UINT8* out,UINT32 len) 00105 { 00106 #ifdef INTEL_IPP_CRYPTO 00107 UINT32 k=len&0xFFFFFFF0; 00108 ippsRijndael128EncryptOFB(in,out,k,16, m_keyAES1,m_iv1); 00109 // if((len%16)!=0) 00110 // { 00111 ippsRijndael128EncryptOFB(in+k,out+k,len%16,len%16, m_keyAES1,m_iv1); 00112 // } 00113 return E_SUCCESS; 00114 #endif 00115 UINT32 i=0; 00116 while(i+15<len) 00117 { 00118 #ifdef INTEL_IPP_CRYPTO 00119 ippsRijndael128EncryptECB(m_iv1,m_iv1,KEY_SIZE, m_keyAES1, IppsCPPaddingNONE); 00120 #else 00121 AES_encrypt(m_iv1,m_iv1,m_keyAES1); 00122 #endif 00123 out[i]=in[i]^m_iv1[0]; 00124 i++; 00125 out[i]=in[i]^m_iv1[1]; 00126 i++; 00127 out[i]=in[i]^m_iv1[2]; 00128 i++; 00129 out[i]=in[i]^m_iv1[3]; 00130 i++; 00131 out[i]=in[i]^m_iv1[4]; 00132 i++; 00133 out[i]=in[i]^m_iv1[5]; 00134 i++; 00135 out[i]=in[i]^m_iv1[6]; 00136 i++; 00137 out[i]=in[i]^m_iv1[7]; 00138 i++; 00139 out[i]=in[i]^m_iv1[8]; 00140 i++; 00141 out[i]=in[i]^m_iv1[9]; 00142 i++; 00143 out[i]=in[i]^m_iv1[10]; 00144 i++; 00145 out[i]=in[i]^m_iv1[11]; 00146 i++; 00147 out[i]=in[i]^m_iv1[12]; 00148 i++; 00149 out[i]=in[i]^m_iv1[13]; 00150 i++; 00151 out[i]=in[i]^m_iv1[14]; 00152 i++; 00153 out[i]=in[i]^m_iv1[15]; 00154 i++; 00155 } 00156 if(i<len) //In this case len-i<16 ! 00157 { 00158 #ifdef INTEL_IPP_CRYPTO 00159 ippsRijndael128EncryptECB(m_iv1,m_iv1,KEY_SIZE, m_keyAES1, IppsCPPaddingNONE); 00160 #else 00161 AES_encrypt(m_iv1,m_iv1,m_keyAES1); 00162 #endif 00163 len-=i; 00164 for(UINT32 k=0; k<len; k++) 00165 { 00166 out[i]=in[i]^m_iv1[k]; 00167 i++; 00168 } 00169 } 00170 return E_SUCCESS; 00171 } 00172 00180 SINT32 CASymCipher::crypt2(const UINT8* in,UINT8* out,UINT32 len) 00181 { 00182 UINT32 i=0; 00183 while(i+15<len) 00184 { 00185 #ifdef INTEL_IPP_CRYPTO 00186 ippsRijndael128EncryptECB(m_iv1,m_iv1,KEY_SIZE, m_keyAES2, IppsCPPaddingNONE); 00187 #else 00188 AES_encrypt(m_iv2,m_iv2,m_keyAES2); 00189 #endif 00190 out[i]=in[i]^m_iv2[0]; 00191 i++; 00192 out[i]=in[i]^m_iv2[1]; 00193 i++; 00194 out[i]=in[i]^m_iv2[2]; 00195 i++; 00196 out[i]=in[i]^m_iv2[3]; 00197 i++; 00198 out[i]=in[i]^m_iv2[4]; 00199 i++; 00200 out[i]=in[i]^m_iv2[5]; 00201 i++; 00202 out[i]=in[i]^m_iv2[6]; 00203 i++; 00204 out[i]=in[i]^m_iv2[7]; 00205 i++; 00206 out[i]=in[i]^m_iv2[8]; 00207 i++; 00208 out[i]=in[i]^m_iv2[9]; 00209 i++; 00210 out[i]=in[i]^m_iv2[10]; 00211 i++; 00212 out[i]=in[i]^m_iv2[11]; 00213 i++; 00214 out[i]=in[i]^m_iv2[12]; 00215 i++; 00216 out[i]=in[i]^m_iv2[13]; 00217 i++; 00218 out[i]=in[i]^m_iv2[14]; 00219 i++; 00220 out[i]=in[i]^m_iv2[15]; 00221 i++; 00222 } 00223 if(i<len) 00224 { 00225 #ifdef INTEL_IPP_CRYPTO 00226 ippsRijndael128EncryptECB(m_iv1,m_iv1,KEY_SIZE, m_keyAES2, IppsCPPaddingNONE); 00227 #else 00228 AES_encrypt(m_iv2,m_iv2,m_keyAES2); 00229 #endif 00230 len-=i; 00231 for(UINT32 k=0; k<len; k++) 00232 { 00233 out[i]=in[i]^m_iv2[k]; 00234 i++; 00235 } 00236 } 00237 return E_SUCCESS; 00238 } 00239 00249 SINT32 CASymCipher::decrypt1CBCwithPKCS7(const UINT8* in,UINT8* out,UINT32* len) 00250 { 00251 if(in==NULL||out==NULL||len==NULL||*len==0) 00252 return E_UNKNOWN; 00253 #ifdef INTEL_IPP_CRYPTO 00254 #else 00255 AES_cbc_encrypt(in,out,*len,m_keyAES1,m_iv1,AES_DECRYPT); 00256 //Now remove padding 00257 UINT32 pad=out[*len-1]; 00258 if(pad>16||pad>*len) 00259 return E_UNKNOWN; 00260 for(UINT32 i=*len-pad; i<*len-1; i++) 00261 if(out[i]!=pad) 00262 return E_UNKNOWN; 00263 *len-=pad; 00264 #endif 00265 return E_SUCCESS; 00266 } 00267 00277 SINT32 CASymCipher::encrypt1CBCwithPKCS7(const UINT8* in,UINT32 inlen,UINT8* out,UINT32* len) 00278 { 00279 #ifdef INTEL_IPP_CRYPTO 00280 #else 00281 UINT32 padlen=16-(inlen%16); 00282 if(inlen+padlen>(*len)) 00283 { 00284 return E_SPACE; 00285 } 00286 UINT8* tmp=new UINT8[inlen+padlen]; 00287 memcpy(tmp,in,inlen); 00288 for(UINT32 i=inlen; i<inlen+padlen; i++) 00289 { 00290 tmp[i]=(UINT8)padlen; 00291 } 00292 AES_cbc_encrypt(tmp,out,inlen+padlen,m_keyAES1,m_iv1,AES_ENCRYPT); 00293 delete[] tmp; 00294 tmp = NULL; 00295 *len=inlen+padlen; 00296 #endif 00297 return E_SUCCESS; 00298 } 00299 00300 SINT32 CASymCipher::testSpeed() 00301 { 00302 const UINT32 runs=1000000; 00303 CASymCipher* pCipher=new CASymCipher(); 00304 UINT8 key[16]; 00305 UINT8* inBuff=new UINT8[1024]; 00306 getRandom(key,16); 00307 getRandom(inBuff,1024); 00308 pCipher->setKey(key); 00309 UINT64 start,end; 00310 getcurrentTimeMillis(start); 00311 for(UINT32 i=0; i<runs; i++) 00312 { 00313 pCipher->crypt1(inBuff,inBuff,1023); 00314 } 00315 getcurrentTimeMillis(end); 00316 UINT32 d=diff64(end,start); 00317 printf("CASymCiper::testSpeed() takes %u ms for %u * 1023 Bytes!\n",d,runs); 00318 return E_SUCCESS; 00319 } 00320 00321 void CASymCipher::setGCMKeys(UINT8* keyRecv, UINT8* keySend) 00322 { 00323 00324 #ifndef USE_OPENSSL_GCM 00325 m_pGCMCtxEnc = new gcm_ctx_64k; 00326 m_pGCMCtxDec = new gcm_ctx_64k; 00327 #else 00328 //Note the have to provide *some* key (OpenSSL API enforced --> so the use the variables we have anyway..) 00329 // The Key will be overriden by a call to setKeyGCM in any case! 00330 AES_set_encrypt_key(m_iv1,128,m_keyAES1); 00331 m_pGCMCtxEnc = CRYPTO_gcm128_new(m_keyAES1,(block128_f)AES_encrypt); 00332 m_pGCMCtxDec = CRYPTO_gcm128_new(m_keyAES1,(block128_f)AES_encrypt); 00333 #endif 00334 00335 00336 00337 #ifndef USE_OPENSSL_GCM 00338 if(m_pGCMCtxDec!=NULL) 00339 delete m_pGCMCtxDec; 00340 if(m_pGCMCtxEnc!=NULL) 00341 delete m_pGCMCtxEnc; 00342 00343 m_pGCMCtxEnc = new gcm_ctx_64k; 00344 m_pGCMCtxDec = new gcm_ctx_64k; 00345 gcm_init_64k(m_pGCMCtxEnc, keySend, 128); 00346 gcm_init_64k(m_pGCMCtxDec, keyRecv, 128); 00347 #else 00348 AES_set_encrypt_key(keyRecv,128,m_keyAES1); 00349 AES_set_encrypt_key(keySend,128,m_keyAES2); 00350 CRYPTO_gcm128_release(m_pGCMCtxEnc); 00351 CRYPTO_gcm128_release(m_pGCMCtxDec); 00352 m_pGCMCtxEnc=CRYPTO_gcm128_new(m_keyAES2,(block128_f)AES_encrypt); 00353 m_pGCMCtxDec=CRYPTO_gcm128_new(m_keyAES1,(block128_f)AES_encrypt); 00354 #endif 00355 //reset IV 00356 m_nEncMsgCounter = 0; 00357 memset(m_pEncMsgIV, 0, 12); 00358 m_nDecMsgCounter = 0; 00359 memset(m_pDecMsgIV, 0, 12); 00360 } 00361 00362 SINT32 CASymCipher::encryptMessage(const UINT8* const in, UINT32 inlen, UINT8* out) 00363 { 00364 //m_pcsEnc->lock(); 00365 m_pEncMsgIV[2] = htonl(m_nEncMsgCounter); 00366 m_nEncMsgCounter++; 00367 #ifndef USE_OPENSSL_GCM 00368 gcm_encrypt_64k(m_pGCMCtxEnc, m_pEncMsgIV, in, inlen, out, (UINT32*)(out + inlen)); 00369 #else 00370 CRYPTO_gcm128_setiv(m_pGCMCtxEnc,(UINT8*)m_pEncMsgIV,12); 00371 CRYPTO_gcm128_encrypt(m_pGCMCtxEnc,in,out,inlen); 00372 CRYPTO_gcm128_tag(m_pGCMCtxEnc,out+inlen,16); 00373 #endif 00374 //m_pcsEnc->unlock(); 00375 return E_SUCCESS; 00376 } 00377 00378 SINT32 CASymCipher::decryptMessage(const UINT8* in, UINT32 inlen, UINT8* out, bool integrityCheck) 00379 { 00380 SINT32 ret = E_UNKNOWN; 00381 //m_pcsDec->lock(); 00382 m_pDecMsgIV[2] = htonl(m_nDecMsgCounter); 00383 if (integrityCheck) 00384 { 00385 m_nDecMsgCounter++; 00386 #ifndef USE_OPENSSL_GCM 00387 ret = ::gcm_decrypt_64k(m_pGCMCtxDec, m_pDecMsgIV, in, inlen - 16, in + inlen - 16, out); 00388 #else 00389 CRYPTO_gcm128_setiv(m_pGCMCtxDec,(UINT8*)m_pDecMsgIV,12); 00390 CRYPTO_gcm128_decrypt(m_pGCMCtxDec,in,out,inlen-16); 00391 ret=CRYPTO_gcm128_finish(m_pGCMCtxDec,in + inlen - 16,16); 00392 #endif 00393 } 00394 else 00395 { 00396 #ifndef USE_OPENSSL_GCM 00397 ret = ::gcm_decrypt_64k(m_pGCMCtxDec, m_pDecMsgIV, in, inlen, out); 00398 #else 00399 CRYPTO_gcm128_setiv(m_pGCMCtxDec,(UINT8*)m_pDecMsgIV,12); 00400 ret=CRYPTO_gcm128_decrypt(m_pGCMCtxDec,in,out,inlen); 00401 #endif 00402 } 00403 //m_pcsDec->unlock(); 00404 #ifndef USE_OPENSSL_GCM 00405 if(ret==0) 00406 #else 00407 if(ret!=0) 00408 #endif 00409 return E_UNKNOWN; 00410 return E_SUCCESS; 00411 }
1.7.6.1