Exemplo n.º 1
0
        public byte[] AES_Decrypt_GCM(byte[] cryptBytes, byte[] Key, byte[] IV, int ks)
        {
            byte[]      iv;
            List <byte> temp = new List <byte> ();

            temp.AddRange(IV);
            temp.AddRange(cryptBytes.Take(8).ToArray());

            iv = temp.ToArray();

            /*
             * The counter array (starting at 2)
             *
             */
            byte[] incr = BitConverter.GetBytes((int)2);
            Array.Reverse(incr);

            /*
             * Counter = First 4 bytes of IV + 8 Random bytes + 4 bytes of sequential value (starting at 2)
             *
             */

            temp.Clear();
            temp.TrimExcess();

            temp.AddRange(iv);
            temp.AddRange(incr);

            byte[] counter = temp.ToArray();

            this.aesctr = new AES_CTR(counter, ks);
            this.ctrenc = aesctr.CreateEncryptor(Key, null);
            byte[] output   = new byte[81920];
            int    numBytes = this.ctrenc.TransformBlock(cryptBytes.Skip(8).Take(cryptBytes.Length - 16).ToArray(), 0, cryptBytes.Length - 8 - 16, output, 0);

            return(output.Take(numBytes).ToArray());
        }
Exemplo n.º 2
0
        /*
         * Receiving seqNum as UInt64 and content_type as byte
         *
         */
        public byte[] AES_Encrypt_GCM(byte[] client_write_key, byte[] client_write_iv, byte[] plaintext, UInt64 seqNum, byte content_type, int ks, Common cf)
        {
            this.cf = cf;

            /*
             * Calculate plaintext size to use later
             *
             */
            int plaintext_size = plaintext.Length;

            /*
             * Initialize a temp list
             *
             */
            List <byte> temp = new List <byte>();

            /*
             * Encrypt a block of 0's and using the key
             *  The result will be H_client
             *
             */
            byte[] init_bytes = new byte[16];
            Array.Clear(init_bytes, 0, 16);

            byte[] encrypted = AES_Encrypt_ECB(init_bytes, client_write_key, ks);
            Array.Reverse(encrypted);
            BigInteger H_client = new BigInteger(encrypted);

            /*
             * BigInteger class considers numbers with MSB (Most Significant Bit) set, as negative.
             *  In such a case, an extra byte 00 is added to the number and converted back to BigInteger
             * More details at the end of the following article:
             *
             * https://msdn.microsoft.com/en-us/library/system.numerics.biginteger(v=vs.110).aspx
             */

            if (H_client < 0)
            {
                temp.Clear();
                temp.TrimExcess();

                temp.AddRange(H_client.ToByteArray());
                temp.Add(0);

                H_client = new BigInteger(temp.ToArray());
            }

            /*
             * Create random number to calculate IV + random
             *  This is concatenated with a counter array and passed to AES_CTR class
             *
             */

            Random rnd = new Random();

            byte[] random = new byte[8];
            rnd.NextBytes(random);

            /*
             * The counter array (starting at 2)
             *
             */
            byte[] incr = BitConverter.GetBytes((int)2);
            Array.Reverse(incr);

            /*
             * Counter = First 4 bytes of IV + 8 Random bytes + 4 bytes of sequential value (starting at 2)
             *
             */

            temp.Clear();
            temp.TrimExcess();

            temp.AddRange(client_write_iv);
            temp.AddRange(random);

            byte[] iv = temp.ToArray();

            temp.AddRange(incr);

            byte[] counter = temp.ToArray();

            /*
             * ctext == Cipher Text
             *
             */
            byte[] ctext;

            /*
             * Plaintext is 16 bytes for Handshake message. Hence, we use TransformFinalBlock here
             *
             */
            this.aesctr = new AES_CTR(counter, ks);
            this.ctrenc = aesctr.CreateEncryptor(client_write_key, null);
            ctext       = this.ctrenc.TransformFinalBlock(plaintext, 0, plaintext_size);

            /*
             * Now creating the AAD
             *  AAD = Sequence Number + Content Type + TLS Version + Plaintext Size
             *
             */
            byte[] seq_num = BitConverter.GetBytes(seqNum);
            Array.Reverse(seq_num);

            /*
             * Using UInt16 instead of short
             *
             */
            byte[] tls_version          = BitConverter.GetBytes((UInt16)771);
            byte[] plaintext_size_array = BitConverter.GetBytes((UInt16)plaintext_size);

            /*
             * Size was returned as 10 00 instead of 00 10
             *
             */
            Array.Reverse(plaintext_size_array);
            temp.Clear();
            temp.TrimExcess();

            temp.AddRange(seq_num);
            temp.Add(content_type);
            temp.AddRange(tls_version);
            temp.AddRange(plaintext_size_array);

            byte[] auth_data = temp.ToArray();

            /*
             * Calculating Auth Tag using GHASH function
             *
             */
            BigInteger auth_tag = GHASH(H_client, auth_data, ctext);

            /*
             * E = ENCRYPTION(IV + "\x00\x00\x00\x01")
             *  Auth Tag = Auth Tag ^ E
             *
             */

            byte[] cval = { 0, 0, 0, 1 };
            temp.Clear();
            temp.TrimExcess();

            temp.AddRange(iv);
            temp.AddRange(cval);

            byte[] encrypted1 = AES_Encrypt_ECB(temp.ToArray(), client_write_key, ks);
            Array.Reverse(encrypted1);

            BigInteger nenc = new BigInteger(encrypted1);

            /*
             * Again if nenc is less than 0, we append a byte of 00 to the end, and convert it back
             *
             */
            if (nenc < 0)
            {
                temp.Clear();
                temp.TrimExcess();

                temp.AddRange(nenc.ToByteArray());
                temp.Add(0);

                nenc = new BigInteger(temp.ToArray());
            }

            auth_tag ^= nenc;

            /*
             * ToByteArray has to be inverted
             *
             */
            byte[] auth_tag_array = auth_tag.ToByteArray();
            Array.Reverse(auth_tag_array);

            if (auth_tag_array[0] == 0x00)
            {
                auth_tag_array = auth_tag_array.Skip(1).ToArray();
            }

            temp.Clear();
            temp.TrimExcess();

            /*
             * Sending random + cipher text + auth_tag_array
             *
             */
            temp.AddRange(random);
            temp.AddRange(ctext);
            temp.AddRange(auth_tag_array);

            return(temp.ToArray());
        }