Exemplo n.º 1
0
        public virtual byte[] DecodeCiphertext(ContentType type, byte[] ciphertext, int offset, int len)
        {
            int blockSize = decryptCipher.GetBlockSize();
            int macSize   = rMac.Size;

            /*
             *  TODO[TLS 1.1] Explicit IV implies minLen = blockSize + max(blockSize, macSize + 1),
             *  and will need further changes to offset and plen variables below.
             */

            int minLen = System.Math.Max(blockSize, macSize + 1);

            if (len < minLen)
            {
                throw new TlsFatalAlert(AlertDescription.decode_error);
            }

            if (len % blockSize != 0)
            {
                throw new TlsFatalAlert(AlertDescription.decryption_failed);
            }

            for (int i = 0; i < len; i += blockSize)
            {
                decryptCipher.ProcessBlock(ciphertext, offset + i, ciphertext, offset + i);
            }

            int plen = len;

            // If there's anything wrong with the padding, this will return zero
            int totalPad = CheckPaddingConstantTime(ciphertext, offset, plen, blockSize, macSize);

            int macInputLen = plen - totalPad - macSize;

            byte[] decryptedMac  = Arrays.Copy(ciphertext, offset + macInputLen, macSize);
            byte[] calculatedMac = rMac.CalculateMacConstantTime(type, ciphertext, offset, macInputLen, plen - macSize, randomData);

            bool badMac = !Arrays.ConstantTimeAreEqual(calculatedMac, decryptedMac);

            if (badMac || totalPad == 0)
            {
                throw new TlsFatalAlert(AlertDescription.bad_record_mac);
            }

            return(Arrays.Copy(ciphertext, offset, macInputLen));
        }
Exemplo n.º 2
0
        /// <exception cref="IOException"></exception>
        public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len)
        {
            int blockSize = decryptCipher.GetBlockSize();
            int macSize   = mReadMac.Size;

            int minLen = blockSize;

            if (encryptThenMac)
            {
                minLen += macSize;
            }
            else
            {
                minLen = System.Math.Max(minLen, macSize + 1);
            }

            if (useExplicitIV)
            {
                minLen += blockSize;
            }

            if (len < minLen)
            {
                throw new TlsFatalAlert(AlertDescription.decode_error);
            }

            int blocks_length = len;

            if (encryptThenMac)
            {
                blocks_length -= macSize;
            }

            if (blocks_length % blockSize != 0)
            {
                throw new TlsFatalAlert(AlertDescription.decryption_failed);
            }

            if (encryptThenMac)
            {
                int    end           = offset + len;
                byte[] receivedMac   = Arrays.CopyOfRange(ciphertext, end - macSize, end);
                byte[] calculatedMac = mReadMac.CalculateMac(seqNo, type, ciphertext, offset, len - macSize);

                bool badMac = !Arrays.ConstantTimeAreEqual(calculatedMac, receivedMac);

                if (badMac)
                {
                    throw new TlsFatalAlert(AlertDescription.bad_record_mac);
                }
            }

            if (useExplicitIV)
            {
                decryptCipher.Init(false, new ParametersWithIV(null, ciphertext, offset, blockSize));

                offset        += blockSize;
                blocks_length -= blockSize;
            }

            for (int i = 0; i < blocks_length; i += blockSize)
            {
                decryptCipher.ProcessBlock(ciphertext, offset + i, ciphertext, offset + i);
            }

            // If there's anything wrong with the padding, this will return zero
            int totalPad = CheckPaddingConstantTime(ciphertext, offset, blocks_length, blockSize, encryptThenMac ? 0 : macSize);

            int dec_output_length = blocks_length - totalPad;

            if (!encryptThenMac)
            {
                dec_output_length -= macSize;
                int    macInputLen   = dec_output_length;
                int    macOff        = offset + macInputLen;
                byte[] receivedMac   = Arrays.CopyOfRange(ciphertext, macOff, macOff + macSize);
                byte[] calculatedMac = mReadMac.CalculateMacConstantTime(seqNo, type, ciphertext, offset, macInputLen,
                                                                         blocks_length - macSize, randomData);

                bool badMac = !Arrays.ConstantTimeAreEqual(calculatedMac, receivedMac);

                if (badMac || totalPad == 0)
                {
                    throw new TlsFatalAlert(AlertDescription.bad_record_mac);
                }
            }

            return(Arrays.CopyOfRange(ciphertext, offset, offset + dec_output_length));
        }
Exemplo n.º 3
0
        /// <exception cref="IOException"></exception>
        public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len)
        {
            int blockSize = decryptCipher.GetBlockSize();
            int macSize   = mReadMac.Size;

            int minLen = blockSize;

            if (encryptThenMac)
            {
                minLen += macSize;
            }
            else
            {
                minLen = System.Math.Max(minLen, macSize + 1);
            }

            if (useExplicitIV)
            {
                minLen += blockSize;
            }

            if (len < minLen)
            {
                throw new TlsFatalAlert(AlertDescription.decode_error);
            }

            int blocks_length = len;

            if (encryptThenMac)
            {
                blocks_length -= macSize;
            }

            if (blocks_length % blockSize != 0)
            {
                throw new TlsFatalAlert(AlertDescription.decryption_failed);
            }

            if (encryptThenMac)
            {
                int    end           = offset + len;
                byte[] receivedMac   = Arrays.CopyOfRange(ciphertext, end - macSize, end);
                byte[] calculatedMac = mReadMac.CalculateMac(seqNo, type, ciphertext, offset, len - macSize);

                bool badMacEtm = !Arrays.ConstantTimeAreEqual(calculatedMac, receivedMac);
                if (badMacEtm)
                {
                    /*
                     * RFC 7366 3. The MAC SHALL be evaluated before any further processing such as
                     * decryption is performed, and if the MAC verification fails, then processing SHALL
                     * terminate immediately. For TLS, a fatal bad_record_mac MUST be generated [2]. For
                     * DTLS, the record MUST be discarded, and a fatal bad_record_mac MAY be generated
                     * [4]. This immediate response to a bad MAC eliminates any timing channels that may
                     * be available through the use of manipulated packet data.
                     */
                    throw new TlsFatalAlert(AlertDescription.bad_record_mac);
                }
            }

            if (useExplicitIV)
            {
                decryptCipher.Init(false, new ParametersWithIV(null, ciphertext, offset, blockSize));

                offset        += blockSize;
                blocks_length -= blockSize;
            }

            for (int i = 0; i < blocks_length; i += blockSize)
            {
                decryptCipher.ProcessBlock(ciphertext, offset + i, ciphertext, offset + i);
            }

            // If there's anything wrong with the padding, this will return zero
            int  totalPad = CheckPaddingConstantTime(ciphertext, offset, blocks_length, blockSize, encryptThenMac ? 0 : macSize);
            bool badMac   = (totalPad == 0);

            int dec_output_length = blocks_length - totalPad;

            if (!encryptThenMac)
            {
                dec_output_length -= macSize;
                int    macInputLen   = dec_output_length;
                int    macOff        = offset + macInputLen;
                byte[] receivedMac   = Arrays.CopyOfRange(ciphertext, macOff, macOff + macSize);
                byte[] calculatedMac = mReadMac.CalculateMacConstantTime(seqNo, type, ciphertext, offset, macInputLen,
                                                                         blocks_length - macSize, randomData);

                badMac |= !Arrays.ConstantTimeAreEqual(calculatedMac, receivedMac);
            }

            if (badMac)
            {
                throw new TlsFatalAlert(AlertDescription.bad_record_mac);
            }

            return(Arrays.CopyOfRange(ciphertext, offset, offset + dec_output_length));
        }
Exemplo n.º 4
0
        public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len)
        {
            int blockSize = decryptCipher.GetBlockSize();
            int size      = mReadMac.Size;
            int num       = blockSize;

            num = ((!encryptThenMac) ? Math.Max(num, size + 1) : (num + size));
            if (useExplicitIV)
            {
                num += blockSize;
            }
            if (len < num)
            {
                throw new TlsFatalAlert(50);
            }
            int num2 = len;

            if (encryptThenMac)
            {
                num2 -= size;
            }
            if (num2 % blockSize != 0)
            {
                throw new TlsFatalAlert(21);
            }
            if (encryptThenMac)
            {
                int    num3 = offset + len;
                byte[] b    = Arrays.CopyOfRange(ciphertext, num3 - size, num3);
                byte[] a    = mReadMac.CalculateMac(seqNo, type, ciphertext, offset, len - size);
                if (!Arrays.ConstantTimeAreEqual(a, b))
                {
                    throw new TlsFatalAlert(20);
                }
            }
            if (useExplicitIV)
            {
                decryptCipher.Init(forEncryption: false, new ParametersWithIV(null, ciphertext, offset, blockSize));
                offset += blockSize;
                num2   -= blockSize;
            }
            for (int i = 0; i < num2; i += blockSize)
            {
                decryptCipher.ProcessBlock(ciphertext, offset + i, ciphertext, offset + i);
            }
            int  num4 = CheckPaddingConstantTime(ciphertext, offset, num2, blockSize, (!encryptThenMac) ? size : 0);
            bool flag = num4 == 0;
            int  num5 = num2 - num4;

            if (!encryptThenMac)
            {
                num5 -= size;
                int    num6 = num5;
                int    num7 = offset + num6;
                byte[] b2   = Arrays.CopyOfRange(ciphertext, num7, num7 + size);
                byte[] a2   = mReadMac.CalculateMacConstantTime(seqNo, type, ciphertext, offset, num6, num2 - size, randomData);
                flag |= !Arrays.ConstantTimeAreEqual(a2, b2);
            }
            if (flag)
            {
                throw new TlsFatalAlert(20);
            }
            return(Arrays.CopyOfRange(ciphertext, offset, offset + num5));
        }