Beispiel #1
0
        public static GarlicMessage AESEncryptGarlic(
            Garlic msg,
            I2PSessionKey sessionkey,
            I2PSessionTag tag,
            List <I2PSessionTag> newtags)
        {
            var cipher = new CbcBlockCipher(new AesEngine());

            var payload = msg.ToByteArray();
            var dest    = new BufLen(new byte[65536]);
            // Reserve header + 4 bytes for GarlicMessageLength
            var writer = new BufRefLen(dest, I2NPMaxHeaderSize + 4);

            // Tag as header
            writer.Write(tag.Value);

            // AES block
            var aesstart = new BufLen(writer);
            var aesblock = new GarlicAESBlock(writer, newtags, null, new BufRefLen(payload));

            var pivh = I2PHashSHA256.GetHash(tag.Value);

            cipher.Init(true, sessionkey.Key.ToParametersWithIV(new BufLen(pivh, 0, 16)));
            cipher.ProcessBytes(aesblock.DataBuf);

            var length = writer - dest;

            dest.PokeFlip32((uint)(length - 4), I2NPMaxHeaderSize);

            return(new GarlicMessage(new BufRefLen(dest, I2NPMaxHeaderSize, length)));
        }
Beispiel #2
0
        public static GarlicMessage EGEncryptGarlic(
            Garlic msg,
            I2PPublicKey pubkey,
            I2PSessionKey sessionkey,
            List <I2PSessionTag> newtags)
        {
            var cipher = new CbcBlockCipher(new AesEngine());

            var payload = msg.ToByteArray();
            var dest    = new BufLen(new byte[65536]);
            // Reserve header + 4 bytes for GarlicMessageLength
            var writer = new BufRefLen(dest, I2NPMaxHeaderSize + 4);

            // ElGamal block
            var egbuf         = new BufLen(new byte[222]);
            var sessionkeybuf = new BufLen(egbuf, 0, 32);
            var preivbuf      = new BufLen(egbuf, 32, 32);
            var egpadding     = new BufLen(egbuf, 64, 158);

            egpadding.Randomize();
            preivbuf.Randomize();
            sessionkeybuf.Poke(sessionkey.Key, 0);

            var iv = new BufLen(I2PHashSHA256.GetHash(preivbuf), 0, 16);

            ElGamalCrypto.Encrypt(writer, egbuf, pubkey, true);

            // AES block
            var aesstart = new BufLen(writer);
            var aesblock = new GarlicAESBlock(writer, newtags, null, new BufRefLen(payload));

            cipher.Init(true, sessionkey.Key.ToParametersWithIV(iv));
            cipher.ProcessBytes(aesblock.DataBuf);

            var length = writer - dest;

            dest.PokeFlip32((uint)(length - 4), I2NPMaxHeaderSize);

            return(new GarlicMessage(new BufRefLen(dest, I2NPMaxHeaderSize, length)));
        }
Beispiel #3
0
        public static (GarlicAESBlock, I2PSessionKey) RetrieveAESBlock(
            GarlicMessage garlic,
            I2PPrivateKey privatekey,
            Func <I2PSessionTag, I2PSessionKey> findsessionkey)
        {
            GarlicAESBlock result;

            var cipher = new CbcBlockCipher(new AesEngine());

            var tag        = new I2PSessionTag(new BufRefLen(garlic.EGData, 0, 32));
            var sessionkey = findsessionkey?.Invoke(tag);

#if LOG_ALL_LEASE_MGMT
            Logging.LogDebug($"Garlic: Session key found {sessionkey}");
#endif
            if (sessionkey != null)
            {
                var aesbuf = new BufLen(garlic.EGData, 32);
                var pivh   = I2PHashSHA256.GetHash(tag.Value);

                cipher.Init(false, sessionkey.Key.ToParametersWithIV(new BufLen(pivh, 0, 16)));
                cipher.ProcessBytes(aesbuf);

                try
                {
                    result = new GarlicAESBlock(new BufRefLen(aesbuf));

                    if (!result.VerifyPayloadHash())
                    {
                        Logging.LogDebug("Garlic: DecryptMessage: AES block SHA256 check failed.");
                        return(null, null);
                    }

                    return(result, sessionkey);
                }
                catch (ArgumentException ex)
                {
                    Logging.Log("Garlic", ex);
                }
                catch (Exception ex)
                {
                    Logging.Log("Garlic", ex);
                    return(null, null);
                }
            }

#if LOG_ALL_LEASE_MGMT
            Logging.LogDebug("Garlic: No session key. Using ElGamal to decrypt.");
#endif

            try
            {
                (result, sessionkey) = Garlic.EGDecryptGarlic(garlic, privatekey);
#if LOG_ALL_LEASE_MGMT
                Logging.LogDebug($"Garlic: EG session key {sessionkey}");
#endif
            }
            catch (Exception ex)
            {
                Logging.LogDebug("Garlic: ElGamal DecryptMessage failed");
                Logging.LogDebugData($"ReceivedSessions {ex}");
                return(null, null);
            }

            return(result, sessionkey);
        }