void GarlicDestination::HandleGarlicMessage (std::shared_ptr<I2NPMessage> msg) { uint8_t * buf = msg->GetPayload (); uint32_t length = bufbe32toh (buf); if (length > msg->GetLength ()) { LogPrint (eLogWarning, "Garlic: message length ", length, " exceeds I2NP message length ", msg->GetLength ()); return; } buf += 4; // length auto it = m_Tags.find (SessionTag(buf)); if (it != m_Tags.end ()) { // tag found. Use AES auto decryption = it->second; m_Tags.erase (it); // tag might be used only once if (length >= 32) { uint8_t iv[32]; // IV is first 16 bytes SHA256(buf, 32, iv); decryption->SetIV (iv); decryption->Decrypt (buf + 32, length - 32, buf + 32); HandleAESBlock (buf + 32, length - 32, decryption, msg->from); } else LogPrint (eLogWarning, "Garlic: message length ", length, " is less than 32 bytes"); } else { // tag not found. Use ElGamal ElGamalBlock elGamal; if (length >= 514 && Decrypt (buf, (uint8_t *)&elGamal, m_Ctx)) { auto decryption = std::make_shared<AESDecryption>(elGamal.sessionKey); uint8_t iv[32]; // IV is first 16 bytes SHA256(elGamal.preIV, 32, iv); decryption->SetIV (iv); decryption->Decrypt(buf + 514, length - 514, buf + 514); HandleAESBlock (buf + 514, length - 514, decryption, msg->from); } else LogPrint (eLogError, "Garlic: Failed to decrypt message"); } }
void Operator::ApplyMagneticBC(bool* dirs) { if (!dirs) return; unsigned int pos[3]; for (int n=0; n<3; ++n) { int nP = (n+1)%3; int nPP = (n+2)%3; for (pos[nP]=0; pos[nP]<numLines[nP]; ++pos[nP]) { for (pos[nPP]=0; pos[nPP]<numLines[nPP]; ++pos[nPP]) { if (dirs[2*n]) { // set to PMC pos[n] = 0; SetII(n, pos[0],pos[1],pos[2], 0 ); SetIV(n, pos[0],pos[1],pos[2], 0 ); SetII(nP, pos[0],pos[1],pos[2], 0 ); SetIV(nP, pos[0],pos[1],pos[2], 0 ); SetII(nPP,pos[0],pos[1],pos[2], 0 ); SetIV(nPP,pos[0],pos[1],pos[2], 0 ); } if (dirs[2*n+1]) { // set to PMC pos[n] = numLines[n]-2; SetII(nP, pos[0],pos[1],pos[2], 0 ); SetIV(nP, pos[0],pos[1],pos[2], 0 ); SetII(nPP,pos[0],pos[1],pos[2], 0 ); SetIV(nPP,pos[0],pos[1],pos[2], 0 ); } // the last current lines are outside the FDTD domain and cannot be iterated by the FDTD engine pos[n] = numLines[n]-1; SetII(n, pos[0],pos[1],pos[2], 0 ); SetIV(n, pos[0],pos[1],pos[2], 0 ); SetII(nP, pos[0],pos[1],pos[2], 0 ); SetIV(nP, pos[0],pos[1],pos[2], 0 ); SetII(nPP,pos[0],pos[1],pos[2], 0 ); SetIV(nPP,pos[0],pos[1],pos[2], 0 ); } } } }
/*---------------------------------------------------------------------- | AP4_CtrStreamCipher::AP4_CtrStreamCipher +---------------------------------------------------------------------*/ AP4_CtrStreamCipher::AP4_CtrStreamCipher(AP4_BlockCipher* block_cipher, AP4_Size counter_size) : m_StreamOffset(0), m_CounterSize(counter_size), m_CacheValid(false), m_BlockCipher(block_cipher) { if (m_CounterSize > 16) m_CounterSize = 16; // reset the stream offset AP4_SetMemory(m_IV, 0, AP4_CIPHER_BLOCK_SIZE); SetStreamOffset(0); SetIV(NULL); }
void Operator::Calc_ECOperatorPos(int n, unsigned int* pos) { unsigned int i = MainOp->SetPos(pos[0],pos[1],pos[2]); if (EC_C[n][i]>0) { SetVV(n,pos[0],pos[1],pos[2], (1-dT*EC_G[n][i]/2/EC_C[n][i])/(1+dT*EC_G[n][i]/2/EC_C[n][i]) ); SetVI(n,pos[0],pos[1],pos[2], (dT/EC_C[n][i])/(1+dT*EC_G[n][i]/2/EC_C[n][i]) ); } else { SetVV(n,pos[0],pos[1],pos[2], 0 ); SetVI(n,pos[0],pos[1],pos[2], 0 ); } if (EC_L[n][i]>0) { SetII(n,pos[0],pos[1],pos[2], (1-dT*EC_R[n][i]/2/EC_L[n][i])/(1+dT*EC_R[n][i]/2/EC_L[n][i]) ); SetIV(n,pos[0],pos[1],pos[2], (dT/EC_L[n][i])/(1+dT*EC_R[n][i]/2/EC_L[n][i]) ); } else { SetII(n,pos[0],pos[1],pos[2], 0 ); SetIV(n,pos[0],pos[1],pos[2], 0 ); } }
void AES::SetIV(const BYTE* iv, int size) { ref<ByteArray> iv_a = gc_new<ByteArray>(iv, size); SetIV(iv_a); }
void GarlicDestination::HandleGarlicMessage (std::shared_ptr<I2NPMessage> msg) { uint8_t * buf = msg->GetPayload (); uint32_t length = bufbe32toh (buf); if (length > msg->GetLength ()) { LogPrint (eLogError, "Garlic message length ", length, " exceeds I2NP message length ", msg->GetLength ()); return; } buf += 4; // length auto it = m_Tags.find (SessionTag(buf)); if (it != m_Tags.end ()) { // tag found. Use AES if (length >= 32) { uint8_t iv[32]; // IV is first 16 bytes CryptoPP::SHA256().CalculateDigest(iv, buf, 32); it->second->SetIV (iv); it->second->Decrypt (buf + 32, length - 32, buf + 32); HandleAESBlock (buf + 32, length - 32, it->second, msg->from); } else LogPrint (eLogError, "Garlic message length ", length, " is less than 32 bytes"); m_Tags.erase (it); // tag might be used only once } else { // tag not found. Use ElGamal ElGamalBlock elGamal; if (length >= 514 && i2p::crypto::ElGamalDecrypt (GetEncryptionPrivateKey (), buf, (uint8_t *)&elGamal, true)) { auto decryption = std::make_shared<i2p::crypto::CBCDecryption>(); decryption->SetKey (elGamal.sessionKey); uint8_t iv[32]; // IV is first 16 bytes CryptoPP::SHA256().CalculateDigest(iv, elGamal.preIV, 32); decryption->SetIV (iv); decryption->Decrypt(buf + 514, length - 514, buf + 514); HandleAESBlock (buf + 514, length - 514, decryption, msg->from); } else LogPrint (eLogError, "Failed to decrypt garlic"); } // cleanup expired tags uint32_t ts = i2p::util::GetSecondsSinceEpoch (); if (ts > m_LastTagsCleanupTime + INCOMING_TAGS_EXPIRATION_TIMEOUT) { if (m_LastTagsCleanupTime) { int numExpiredTags = 0; for (auto it = m_Tags.begin (); it != m_Tags.end ();) { if (ts > it->first.creationTime + INCOMING_TAGS_EXPIRATION_TIMEOUT) { numExpiredTags++; it = m_Tags.erase (it); } else it++; } LogPrint (numExpiredTags, " tags expired for ", GetIdentHash().ToBase64 ()); } m_LastTagsCleanupTime = ts; } }