|
Mixe for Privacy and Anonymity in the Internet
|
This class could be used for encryption/decryption of data (streams) with AES using 128bit OFB mode. More...
#include <CASymCipher.hpp>
Public Member Functions | |
| CASymCipher () | |
| ~CASymCipher () | |
| bool | isKeyValid () |
| SINT32 | setKey (const UINT8 *key) |
| Sets the keys for crypt1() and crypt2() to the same key. | |
| SINT32 | setKeys (const UINT8 *key, UINT32 keysize) |
| Sets the keys for crypt1() and crypt2() either to the same key (if keysize==KEY_SIZE) or to different values, if keysize==2* KEY_SIZE. | |
| SINT32 | setKey (const UINT8 *key, bool bEncrypt) |
| Sets the key1 and key2 used for encryption/decryption to the same value of key. | |
| SINT32 | setIVs (const UINT8 *p_iv) |
| Sets iv1 and iv2 to p_iv. | |
| SINT32 | setIV2 (const UINT8 *p_iv) |
| Sets iv2 to p_iv. | |
| SINT32 | crypt1 (const UINT8 *in, UINT8 *out, UINT32 len) |
| Encryptes/Decrpytes in to out using iv1 and key1. | |
| SINT32 | crypt2 (const UINT8 *in, UINT8 *out, UINT32 len) |
| Decryptes in to out using iv2 and key2. | |
| SINT32 | decrypt1CBCwithPKCS7 (const UINT8 *in, UINT8 *out, UINT32 *len) |
| En-/Decryptes in to out using iv1 and key1. | |
| SINT32 | encrypt1CBCwithPKCS7 (const UINT8 *in, UINT32 inlen, UINT8 *out, UINT32 *len) |
| En-/Decryptes in to out using IV1 and key1. | |
| void | setGCMKeys (UINT8 *keyRecv, UINT8 *keySend) |
| SINT32 | encryptMessage (const UINT8 *in, UINT32 inlen, UINT8 *out) |
| SINT32 | decryptMessage (const UINT8 *in, UINT32 inlen, UINT8 *out, bool integrityCheck) |
Static Public Member Functions | |
| static SINT32 | testSpeed () |
Protected Attributes | |
| AES_KEY * | m_keyAES1 |
| AES_KEY * | m_keyAES2 |
| UINT8 * | m_iv1 |
| UINT8 * | m_iv2 |
| bool | m_bKeySet |
Private Attributes | |
| CAMutex * | m_pcsEnc |
| CAMutex * | m_pcsDec |
| gcm_ctx_64k * | m_pGCMCtxEnc |
| gcm_ctx_64k * | m_pGCMCtxDec |
| UINT32 | m_nEncMsgCounter |
| UINT32 * | m_pEncMsgIV |
| UINT32 | m_nDecMsgCounter |
| UINT32 * | m_pDecMsgIV |
This class could be used for encryption/decryption of data (streams) with AES using 128bit OFB mode.
Because of the OFB mode technical encryption and decrpytion are the same (depending on the kind of input). Therefore there is only a general crypt() function. This class has a 2-in-1 feature: Two independent IVs are available. Therefore we have crypt1() and crypt2() depending on the used IV.
Definition at line 42 of file CASymCipher.hpp.
| CASymCipher::CASymCipher | ( | ) | [inline] |
Definition at line 48 of file CASymCipher.hpp.
References m_bKeySet, m_iv1, m_iv2, m_keyAES1, m_keyAES2, m_nDecMsgCounter, m_nEncMsgCounter, m_pcsDec, m_pcsEnc, m_pDecMsgIV, m_pEncMsgIV, m_pGCMCtxDec, and m_pGCMCtxEnc.
Referenced by testSpeed().
{
m_bKeySet=false;
#ifdef INTEL_IPP_CRYPTO
int size=0;
ippsRijndael128GetSize(&size);
m_keyAES1=(IppsRijndael128Spec*)new UINT8[size];
m_keyAES2=(IppsRijndael128Spec*)new UINT8[size];
#else
m_keyAES1=new AES_KEY;
m_keyAES2=new AES_KEY;
#endif
m_iv1=new UINT8[16];
m_iv2=new UINT8[16];
m_nEncMsgCounter = 0;
m_pEncMsgIV = new UINT32[3];
memset(m_pEncMsgIV, 0, 12);
m_nDecMsgCounter = 0;
m_pDecMsgIV = new UINT32[3];
memset(m_pDecMsgIV, 0, 12);
m_pGCMCtxEnc = NULL;
m_pGCMCtxDec = NULL;
m_pcsEnc = new CAMutex();
m_pcsDec = new CAMutex();
}
| CASymCipher::~CASymCipher | ( | ) | [inline] |
Definition at line 77 of file CASymCipher.hpp.
References m_iv1, m_iv2, m_keyAES1, m_keyAES2, m_pcsDec, m_pcsEnc, m_pDecMsgIV, m_pEncMsgIV, m_pGCMCtxDec, m_pGCMCtxEnc, and CALockAble::waitForDestroy().
{
#ifndef ONLY_LOCAL_PROXY
waitForDestroy();
#endif
#ifdef INTEL_IPP_CRYPTO
delete[] (UINT8*)m_keyAES1;
delete[] (UINT8*)m_keyAES2;
#else
delete m_keyAES1;
delete m_keyAES2;
#endif
m_keyAES1 = NULL;
m_keyAES2 = NULL;
delete[] m_iv1;
m_iv1 = NULL;
delete[] m_iv2;
m_iv2 = NULL;
delete [] m_pEncMsgIV;
m_pEncMsgIV = NULL;
delete [] m_pDecMsgIV;
m_pDecMsgIV = NULL;
delete m_pGCMCtxEnc;
m_pGCMCtxEnc = NULL;
delete m_pGCMCtxDec;
m_pGCMCtxDec = NULL;
delete m_pcsEnc;
m_pcsEnc = NULL;
delete m_pcsDec;
m_pcsDec = NULL;
}
| SINT32 CASymCipher::crypt1 | ( | const UINT8 * | in, |
| UINT8 * | out, | ||
| UINT32 | len | ||
| ) |
Encryptes/Decrpytes in to out using iv1 and key1.
AES is used for encryption and the encryption is done with a special 128bit-OFB mode: In the case that (len mod 16 !=0) the unused cipher output bits are discarded and NOT used next time encryptAES() is called. That means that every time encrpytAES() is called at first new cipher output is created by calling AES-encrypt(iv).
| in | input (plain text) bytes |
| out | output (encrpyted) bytes |
| len | len of input. because the cipher preserves the size, len of output=len of input |
| E_SUCCESS |
Definition at line 104 of file CASymCipher.cpp.
References E_SUCCESS, KEY_SIZE, len, m_iv1, and m_keyAES1.
Referenced by CALastMixA::loop(), CAFirstMixB::loop(), CAFirstMixA::loop(), CALastMixB::loop(), CALocalProxy::loop(), mm_loopReadFromMixBefore(), CAMuxSocket::prepareForSend(), CAMuxSocket::receive(), CAMuxSocket::send(), and testSpeed().
{
#ifdef INTEL_IPP_CRYPTO
UINT32 k=len&0xFFFFFFF0;
ippsRijndael128EncryptOFB(in,out,k,16, m_keyAES1,m_iv1);
// if((len%16)!=0)
// {
ippsRijndael128EncryptOFB(in+k,out+k,len%16,len%16, m_keyAES1,m_iv1);
// }
return E_SUCCESS;
#endif
UINT32 i=0;
while(i+15<len)
{
#ifdef INTEL_IPP_CRYPTO
ippsRijndael128EncryptECB(m_iv1,m_iv1,KEY_SIZE, m_keyAES1, IppsCPPaddingNONE);
#else
AES_encrypt(m_iv1,m_iv1,m_keyAES1);
#endif
out[i]=in[i]^m_iv1[0];
i++;
out[i]=in[i]^m_iv1[1];
i++;
out[i]=in[i]^m_iv1[2];
i++;
out[i]=in[i]^m_iv1[3];
i++;
out[i]=in[i]^m_iv1[4];
i++;
out[i]=in[i]^m_iv1[5];
i++;
out[i]=in[i]^m_iv1[6];
i++;
out[i]=in[i]^m_iv1[7];
i++;
out[i]=in[i]^m_iv1[8];
i++;
out[i]=in[i]^m_iv1[9];
i++;
out[i]=in[i]^m_iv1[10];
i++;
out[i]=in[i]^m_iv1[11];
i++;
out[i]=in[i]^m_iv1[12];
i++;
out[i]=in[i]^m_iv1[13];
i++;
out[i]=in[i]^m_iv1[14];
i++;
out[i]=in[i]^m_iv1[15];
i++;
}
if(i<len) //In this case len-i<16 !
{
#ifdef INTEL_IPP_CRYPTO
ippsRijndael128EncryptECB(m_iv1,m_iv1,KEY_SIZE, m_keyAES1, IppsCPPaddingNONE);
#else
AES_encrypt(m_iv1,m_iv1,m_keyAES1);
#endif
len-=i;
for(UINT32 k=0;k<len;k++)
{
out[i]=in[i]^m_iv1[k];
i++;
}
}
return E_SUCCESS;
}
| SINT32 CASymCipher::crypt2 | ( | const UINT8 * | in, |
| UINT8 * | out, | ||
| UINT32 | len | ||
| ) |
Decryptes in to out using iv2 and key2.
| in | input (encrypted) bytes |
| out | output (decrpyted) bytes |
| len | len of input. because the cipher preserves the size, len of output=len of input |
| E_SUCCESS |
Definition at line 180 of file CASymCipher.cpp.
References E_SUCCESS, KEY_SIZE, len, m_iv1, m_iv2, and m_keyAES2.
Referenced by CALastMixA::loop(), CAFirstMixB::loop(), CAFirstMixA::loop(), CALocalProxy::loop(), mm_loopReadFromMixAfter(), and CAChain::processDownstream().
{
UINT32 i=0;
while(i+15<len)
{
#ifdef INTEL_IPP_CRYPTO
ippsRijndael128EncryptECB(m_iv1,m_iv1,KEY_SIZE, m_keyAES2, IppsCPPaddingNONE);
#else
AES_encrypt(m_iv2,m_iv2,m_keyAES2);
#endif
out[i]=in[i]^m_iv2[0];
i++;
out[i]=in[i]^m_iv2[1];
i++;
out[i]=in[i]^m_iv2[2];
i++;
out[i]=in[i]^m_iv2[3];
i++;
out[i]=in[i]^m_iv2[4];
i++;
out[i]=in[i]^m_iv2[5];
i++;
out[i]=in[i]^m_iv2[6];
i++;
out[i]=in[i]^m_iv2[7];
i++;
out[i]=in[i]^m_iv2[8];
i++;
out[i]=in[i]^m_iv2[9];
i++;
out[i]=in[i]^m_iv2[10];
i++;
out[i]=in[i]^m_iv2[11];
i++;
out[i]=in[i]^m_iv2[12];
i++;
out[i]=in[i]^m_iv2[13];
i++;
out[i]=in[i]^m_iv2[14];
i++;
out[i]=in[i]^m_iv2[15];
i++;
}
if(i<len)
{
#ifdef INTEL_IPP_CRYPTO
ippsRijndael128EncryptECB(m_iv1,m_iv1,KEY_SIZE, m_keyAES2, IppsCPPaddingNONE);
#else
AES_encrypt(m_iv2,m_iv2,m_keyAES2);
#endif
len-=i;
for(UINT32 k=0;k<len;k++)
{
out[i]=in[i]^m_iv2[k];
i++;
}
}
return E_SUCCESS;
}
| SINT32 CASymCipher::decrypt1CBCwithPKCS7 | ( | const UINT8 * | in, |
| UINT8 * | out, | ||
| UINT32 * | len | ||
| ) |
En-/Decryptes in to out using iv1 and key1.
AES is used for en-/dcryption and the cryption is done with CBC mode and PKCS7 padding.
| in | input (plain or ciphertext) bytes |
| out | output (plain or ciphertext) bytes |
| len | len of input. on return the output len, which is always <= len of input |
| E_SUCCESS | |
| E_UNKNOWN,if | error |
Definition at line 249 of file CASymCipher.cpp.
References E_SUCCESS, E_UNKNOWN, m_iv1, and m_keyAES1.
Referenced by decryptXMLElement().
{
if(in==NULL||out==NULL||len==NULL||*len==0)
return E_UNKNOWN;
#ifdef INTEL_IPP_CRYPTO
#else
AES_cbc_encrypt(in,out,*len,m_keyAES1,m_iv1,AES_DECRYPT);
//Now remove padding
UINT32 pad=out[*len-1];
if(pad>16||pad>*len)
return E_UNKNOWN;
for(UINT32 i=*len-pad;i<*len-1;i++)
if(out[i]!=pad)
return E_UNKNOWN;
*len-=pad;
#endif
return E_SUCCESS;
}
| SINT32 CASymCipher::decryptMessage | ( | const UINT8 * | in, |
| UINT32 | inlen, | ||
| UINT8 * | out, | ||
| bool | integrityCheck | ||
| ) |
Definition at line 338 of file CASymCipher.cpp.
References m_nDecMsgCounter, m_pDecMsgIV, and m_pGCMCtxDec.
Referenced by CALastMixA::loop().
{
SINT32 ret = 0;
//m_pcsDec->lock();
m_pDecMsgIV[2] = htonl(m_nDecMsgCounter);
if (integrityCheck)
{
m_nDecMsgCounter++;
ret = ::gcm_decrypt_64k(m_pGCMCtxDec, m_pDecMsgIV, in, inlen - 16, in + inlen - 16, out);
}
else
{
ret = ::gcm_decrypt_64k(m_pGCMCtxDec, m_pDecMsgIV, in, inlen, out);
}
//m_pcsDec->unlock();
return ret;
}
| SINT32 CASymCipher::encrypt1CBCwithPKCS7 | ( | const UINT8 * | in, |
| UINT32 | inlen, | ||
| UINT8 * | out, | ||
| UINT32 * | len | ||
| ) |
En-/Decryptes in to out using IV1 and key1.
AES is used for en-/decryption and the cryption is done with CBC mode and PKCS7 padding.
| in | input (plain or ciphertext) bytes |
| inlen | size of the input buffer |
| out | output (plain or ciphertext) bytes |
| len | on call len of output buffer; on return size of output buffer used, which is always > len of input |
| E_SUCCESS |
Definition at line 277 of file CASymCipher.cpp.
References E_SPACE, E_SUCCESS, m_iv1, and m_keyAES1.
Referenced by encryptXMLElement().
{
#ifdef INTEL_IPP_CRYPTO
#else
UINT32 padlen=16-(inlen%16);
if(inlen+padlen>(*len))
{
return E_SPACE;
}
UINT8* tmp=new UINT8[inlen+padlen];
memcpy(tmp,in,inlen);
for(UINT32 i=inlen;i<inlen+padlen;i++)
{
tmp[i]=(UINT8)padlen;
}
AES_cbc_encrypt(tmp,out,inlen+padlen,m_keyAES1,m_iv1,AES_ENCRYPT);
delete[] tmp;
tmp = NULL;
*len=inlen+padlen;
#endif
return E_SUCCESS;
}
| SINT32 CASymCipher::encryptMessage | ( | const UINT8 * | in, |
| UINT32 | inlen, | ||
| UINT8 * | out | ||
| ) |
Definition at line 328 of file CASymCipher.cpp.
References E_SUCCESS, m_nEncMsgCounter, m_pEncMsgIV, and m_pGCMCtxEnc.
Referenced by CALastMixA::loop().
{
//m_pcsEnc->lock();
m_pEncMsgIV[2] = htonl(m_nEncMsgCounter);
m_nEncMsgCounter++;
gcm_encrypt_64k(m_pGCMCtxEnc, m_pEncMsgIV, in, inlen, out, (UINT32*)(out + inlen));
//m_pcsEnc->unlock();
return E_SUCCESS;
}
| bool CASymCipher::isKeyValid | ( | ) | [inline] |
Definition at line 112 of file CASymCipher.hpp.
References m_bKeySet.
Referenced by CALocalProxy::loop().
{
return m_bKeySet;
}
| void CASymCipher::setGCMKeys | ( | UINT8 * | keyRecv, |
| UINT8 * | keySend | ||
| ) |
Definition at line 321 of file CASymCipher.cpp.
References m_pGCMCtxDec, and m_pGCMCtxEnc.
Referenced by CALastMixA::loop().
{
m_pGCMCtxEnc = new gcm_ctx_64k;
m_pGCMCtxDec = new gcm_ctx_64k;
gcm_init_64k(m_pGCMCtxEnc, keySend, 128);
gcm_init_64k(m_pGCMCtxDec, keyRecv, 128);
}
| SINT32 CASymCipher::setIV2 | ( | const UINT8 * | p_iv | ) | [inline] |
Sets iv2 to p_iv.
| p_iv | 16 random bytes used for new iv2. |
| E_SUCCESS |
Definition at line 141 of file CASymCipher.hpp.
References E_SUCCESS, and m_iv2.
Referenced by CAFirstMixB::loop(), CAFirstMixA::loop(), and CALocalProxy::loop().
| SINT32 CASymCipher::setIVs | ( | const UINT8 * | p_iv | ) | [inline] |
Sets iv1 and iv2 to p_iv.
| p_iv | 16 random bytes used for new iv1 and iv2. |
| E_SUCCESS |
Definition at line 130 of file CASymCipher.hpp.
References E_SUCCESS, m_iv1, and m_iv2.
Referenced by decryptXMLElement(), CAFirstMix::doUserLogin_internal(), encryptXMLElement(), CALocalProxy::processKeyExchange(), CAMuxSocket::setReceiveKey(), and CAMuxSocket::setSendKey().
| SINT32 CASymCipher::setKey | ( | const UINT8 * | key | ) |
Sets the keys for crypt1() and crypt2() to the same key.
Sets the key1 and key2 used for encryption/decryption.
Also resets the IVs to zero!
| key | 16 random bytes used as key |
| E_SUCCESS |
Definition at line 36 of file CASymCipher.cpp.
Referenced by decryptXMLElement(), CAFirstMix::doUserLogin_internal(), encryptXMLElement(), CAFirstMixB::loop(), CALastMixB::loop(), CALocalProxy::processKeyExchange(), CAMuxSocket::setKey(), setKeys(), CAMuxSocket::setReceiveKey(), CAMuxSocket::setSendKey(), and testSpeed().
{
return setKey(key,true);
}
| SINT32 CASymCipher::setKey | ( | const UINT8 * | key, |
| bool | bEncrypt | ||
| ) |
Sets the key1 and key2 used for encryption/decryption to the same value of key.
Also resets the IVs to zero!
| key | 16 random bytes used as key |
| bEncrypt | if true, the key should be used for encryption (otherwise it will be used for decryption) |
| E_SUCCESS |
Definition at line 46 of file CASymCipher.cpp.
References E_SUCCESS, m_bKeySet, m_iv1, m_iv2, m_keyAES1, and m_keyAES2.
{
#ifdef INTEL_IPP_CRYPTO
ippsRijndael128Init(key, IppsRijndaelKey128,m_keyAES1);
ippsRijndael128Init(key, IppsRijndaelKey128,m_keyAES2);
#else
if(bEncrypt)
{
AES_set_encrypt_key(key,128,m_keyAES1);
AES_set_encrypt_key(key,128,m_keyAES2);
}
else
{
AES_set_decrypt_key(key,128,m_keyAES1);
AES_set_decrypt_key(key,128,m_keyAES2);
}
#endif
memset(m_iv1,0,16);
memset(m_iv2,0,16);
m_bKeySet=true;
return E_SUCCESS;
}
| SINT32 CASymCipher::setKeys | ( | const UINT8 * | key, |
| UINT32 | keysize | ||
| ) |
Sets the keys for crypt1() and crypt2() either to the same key (if keysize==KEY_SIZE) or to different values, if keysize==2* KEY_SIZE.
Definition at line 69 of file CASymCipher.cpp.
References E_SUCCESS, E_UNKNOWN, KEY_SIZE, m_bKeySet, m_iv1, m_iv2, m_keyAES1, m_keyAES2, and setKey().
Referenced by CALastMixA::loop(), CAFirstMixA::loop(), CALocalProxy::loop(), and mm_loopReadFromMixBefore().
{
if(keysize==KEY_SIZE)
{
return setKey(key);
}
else if(keysize==2*KEY_SIZE)
{
#ifdef INTEL_IPP_CRYPTO
ippsRijndael128Init(key, IppsRijndaelKey128,m_keyAES1);
ippsRijndael128Init(key+KEY_SIZE, IppsRijndaelKey128,m_keyAES2);
#else
AES_set_encrypt_key(key,128,m_keyAES1);
AES_set_encrypt_key(key+KEY_SIZE,128,m_keyAES2);
#endif
memset(m_iv1,0,16);
memset(m_iv2,0,16);
m_bKeySet=true;
return E_SUCCESS;
}
return E_UNKNOWN;
}
| SINT32 CASymCipher::testSpeed | ( | ) | [static] |
Definition at line 300 of file CASymCipher.cpp.
References CASymCipher(), crypt1(), diff64(), E_SUCCESS, getcurrentTimeMillis(), getRandom(), and setKey().
{
const UINT32 runs=1000000;
CASymCipher* pCipher=new CASymCipher();
UINT8 key[16];
UINT8* inBuff=new UINT8[1024];
getRandom(key,16);
getRandom(inBuff,1024);
pCipher->setKey(key);
UINT64 start,end;
getcurrentTimeMillis(start);
for(UINT32 i=0;i<runs;i++)
{
pCipher->crypt1(inBuff,inBuff,1023);
}
getcurrentTimeMillis(end);
UINT32 d=diff64(end,start);
printf("CASymCiper::testSpeed() takes %u ms for %u * 1023 Bytes!\n",d,runs);
return E_SUCCESS;
}
bool CASymCipher::m_bKeySet [protected] |
Definition at line 180 of file CASymCipher.hpp.
Referenced by CASymCipher(), isKeyValid(), setKey(), and setKeys().
UINT8* CASymCipher::m_iv1 [protected] |
Definition at line 178 of file CASymCipher.hpp.
Referenced by CASymCipher(), crypt1(), crypt2(), decrypt1CBCwithPKCS7(), encrypt1CBCwithPKCS7(), setIVs(), setKey(), setKeys(), and ~CASymCipher().
UINT8* CASymCipher::m_iv2 [protected] |
Definition at line 179 of file CASymCipher.hpp.
Referenced by CASymCipher(), crypt2(), setIV2(), setIVs(), setKey(), setKeys(), and ~CASymCipher().
AES_KEY* CASymCipher::m_keyAES1 [protected] |
Definition at line 174 of file CASymCipher.hpp.
Referenced by CASymCipher(), crypt1(), decrypt1CBCwithPKCS7(), encrypt1CBCwithPKCS7(), setKey(), setKeys(), and ~CASymCipher().
AES_KEY* CASymCipher::m_keyAES2 [protected] |
Definition at line 175 of file CASymCipher.hpp.
Referenced by CASymCipher(), crypt2(), setKey(), setKeys(), and ~CASymCipher().
UINT32 CASymCipher::m_nDecMsgCounter [private] |
Definition at line 165 of file CASymCipher.hpp.
Referenced by CASymCipher(), and decryptMessage().
UINT32 CASymCipher::m_nEncMsgCounter [private] |
Definition at line 163 of file CASymCipher.hpp.
Referenced by CASymCipher(), and encryptMessage().
CAMutex* CASymCipher::m_pcsDec [private] |
Definition at line 160 of file CASymCipher.hpp.
Referenced by CASymCipher(), and ~CASymCipher().
CAMutex* CASymCipher::m_pcsEnc [private] |
Definition at line 159 of file CASymCipher.hpp.
Referenced by CASymCipher(), and ~CASymCipher().
UINT32* CASymCipher::m_pDecMsgIV [private] |
Definition at line 166 of file CASymCipher.hpp.
Referenced by CASymCipher(), decryptMessage(), and ~CASymCipher().
UINT32* CASymCipher::m_pEncMsgIV [private] |
Definition at line 164 of file CASymCipher.hpp.
Referenced by CASymCipher(), encryptMessage(), and ~CASymCipher().
gcm_ctx_64k* CASymCipher::m_pGCMCtxDec [private] |
Definition at line 162 of file CASymCipher.hpp.
Referenced by CASymCipher(), decryptMessage(), setGCMKeys(), and ~CASymCipher().
gcm_ctx_64k* CASymCipher::m_pGCMCtxEnc [private] |
Definition at line 161 of file CASymCipher.hpp.
Referenced by CASymCipher(), encryptMessage(), setGCMKeys(), and ~CASymCipher().
1.7.6.1