Example #1
0
        public void ExponentiateX(long pow, byte[] output)
        {
            // Initial value is little-endian 1
            ulong[] y = GcmUtilities.OneAsUlongs();

            if (pow > 0)
            {
                ulong[] powX = Arrays.Clone(x);
                do
                {
                    if ((pow & 1L) != 0)
                    {
                        GcmUtilities.Multiply(y, powX);
                    }
                    GcmUtilities.Square(powX, powX);
                    pow >>= 1;
                }while (pow > 0);
            }

            GcmUtilities.AsBytes(y, output);
        }
Example #2
0
        public int DoFinal(byte[] output, int outOff)
        {
            if (totalLength == 0)
            {
                InitCipher();
            }
            int num = bufOff;

            if (forEncryption)
            {
                Check.OutputLength(output, outOff, num + macSize, "Output buffer too short");
            }
            else
            {
                if (num < macSize)
                {
                    throw new InvalidCipherTextException("data too short");
                }
                num -= macSize;
                Check.OutputLength(output, outOff, num, "Output buffer too short");
            }
            if (num > 0)
            {
                gCTRPartial(bufBlock, 0, num, output, outOff);
            }
            atLength += (uint)atBlockPos;
            if (atLength > atLengthPre)
            {
                if (atBlockPos > 0)
                {
                    gHASHPartial(S_at, atBlock, 0, atBlockPos);
                }
                if (atLengthPre != 0)
                {
                    GcmUtilities.Xor(S_at, S_atPre);
                }
                long   pow   = (long)(totalLength * 8 + 127 >> 7);
                byte[] array = new byte[16];
                if (exp == null)
                {
                    exp = new Tables1kGcmExponentiator();
                    exp.Init(H);
                }
                exp.ExponentiateX(pow, array);
                GcmUtilities.Multiply(S_at, array);
                GcmUtilities.Xor(S, S_at);
            }
            byte[] array2 = new byte[16];
            Pack.UInt64_To_BE(atLength * 8, array2, 0);
            Pack.UInt64_To_BE(totalLength * 8, array2, 8);
            gHASHBlock(S, array2);
            byte[] array3 = new byte[16];
            cipher.ProcessBlock(J0, 0, array3, 0);
            GcmUtilities.Xor(array3, S);
            int num2 = num;

            macBlock = new byte[macSize];
            global::System.Array.Copy((global::System.Array)array3, 0, (global::System.Array)macBlock, 0, macSize);
            if (forEncryption)
            {
                global::System.Array.Copy((global::System.Array)macBlock, 0, (global::System.Array)output, outOff + bufOff, macSize);
                num2 += macSize;
            }
            else
            {
                byte[] array4 = new byte[macSize];
                global::System.Array.Copy((global::System.Array)bufBlock, num, (global::System.Array)array4, 0, macSize);
                if (!Arrays.ConstantTimeAreEqual(macBlock, array4))
                {
                    throw new InvalidCipherTextException("mac check in GCM failed");
                }
            }
            Reset(clearMac: false);
            return(num2);
        }
        // Token: 0x060000E8 RID: 232 RVA: 0x0000827C File Offset: 0x0000647C
        public int DoFinal(byte[] output, int outOff)
        {
            this.CheckStatus();
            if (this.totalLength == 0UL)
            {
                this.InitCipher();
            }
            int num = this.bufOff;

            if (this.forEncryption)
            {
                Check.OutputLength(output, outOff, num + this.macSize, "Output buffer too short");
            }
            else
            {
                if (num < this.macSize)
                {
                    throw new CryptoException("data too short");
                }
                num -= this.macSize;
                Check.OutputLength(output, outOff, num, "Output buffer too short");
            }
            if (num > 0)
            {
                this.ProcessPartial(this.bufBlock, 0, num, output, outOff);
            }
            this.atLength += (ulong)this.atBlockPos;
            if (this.atLength > this.atLengthPre)
            {
                if (this.atBlockPos > 0)
                {
                    this.gHASHPartial(this.S_at, this.atBlock, 0, this.atBlockPos);
                }
                if (this.atLengthPre > 0UL)
                {
                    GcmUtilities.Xor(this.S_at, this.S_atPre);
                }
                long   pow   = (long)(this.totalLength * 8UL + 127UL >> 7);
                byte[] array = new byte[16];
                if (this.exp == null)
                {
                    this.exp = new Tables1kGcmExponentiator();
                    this.exp.Init(this.H);
                }
                this.exp.ExponentiateX(pow, array);
                GcmUtilities.Multiply(this.S_at, array);
                GcmUtilities.Xor(this.S, this.S_at);
            }
            byte[] array2 = new byte[16];
            Pack.UInt64_To_BE(this.atLength * 8UL, array2, 0);
            Pack.UInt64_To_BE(this.totalLength * 8UL, array2, 8);
            this.gHASHBlock(this.S, array2);
            byte[] array3 = new byte[16];
            this.cipher.ProcessBlock(this.J0, 0, array3, 0);
            GcmUtilities.Xor(array3, this.S);
            int num2 = num;

            this.macBlock = new byte[this.macSize];
            Array.Copy(array3, 0, this.macBlock, 0, this.macSize);
            if (this.forEncryption)
            {
                Array.Copy(this.macBlock, 0, output, outOff + this.bufOff, this.macSize);
                num2 += this.macSize;
            }
            else
            {
                byte[] array4 = new byte[this.macSize];
                Array.Copy(this.bufBlock, num, array4, 0, this.macSize);
                if (!Arrays.ConstantTimeAreEqual(this.macBlock, array4))
                {
                    throw new CryptoException("mac check in GCM failed");
                }
            }
            this.Reset(false);
            return(num2);
        }
Example #4
0
 public void MultiplyH(byte[] x)
 {
     uint[] x2 = GcmUtilities.AsUints(x);
     GcmUtilities.Multiply(x2, H);
     GcmUtilities.AsBytes(x2, x);
 }
Example #5
0
        public int DoFinal(byte[] output, int outOff)
        {
            if (totalLength == 0)
            {
                InitCipher();
            }

            int extra = bufOff;

            if (forEncryption)
            {
                Check.OutputLength(output, outOff, extra + macSize, "Output buffer too short");
            }
            else
            {
                if (extra < macSize)
                {
                    throw new InvalidCipherTextException("data too short");
                }

                extra -= macSize;

                Check.OutputLength(output, outOff, extra, "Output buffer too short");
            }

            if (extra > 0)
            {
                gCTRPartial(bufBlock, 0, extra, output, outOff);
            }

            atLength += (uint)atBlockPos;

            if (atLength > atLengthPre)
            {
                /*
                 *  Some AAD was sent after the cipher started. We determine the difference b/w the hash value
                 *  we actually used when the cipher started (S_atPre) and the final hash value calculated (S_at).
                 *  Then we carry this difference forward by multiplying by H^c, where c is the number of (full or
                 *  partial) cipher-text blocks produced, and adjust the current hash.
                 */

                // Finish hash for partial AAD block
                if (atBlockPos > 0)
                {
                    gHASHPartial(S_at, atBlock, 0, atBlockPos);
                }

                // Find the difference between the AAD hashes
                if (atLengthPre > 0)
                {
                    GcmUtilities.Xor(S_at, S_atPre);
                }

                // Number of cipher-text blocks produced
                long c = (long)(((totalLength * 8) + 127) >> 7);

                // Calculate the adjustment factor
                byte[] H_c = new byte[16];
                if (exp == null)
                {
                    exp = new Tables1kGcmExponentiator();
                    exp.Init(H);
                }
                exp.ExponentiateX(c, H_c);

                // Carry the difference forward
                GcmUtilities.Multiply(S_at, H_c);

                // Adjust the current hash
                GcmUtilities.Xor(S, S_at);
            }

            // Final gHASH
            byte[] X = new byte[BlockSize];
            Pack.UInt64_To_BE(atLength * 8UL, X, 0);
            Pack.UInt64_To_BE(totalLength * 8UL, X, 8);

            gHASHBlock(S, X);

            // T = MSBt(GCTRk(J0,S))
            byte[] tag = new byte[BlockSize];
            cipher.ProcessBlock(J0, 0, tag, 0);
            GcmUtilities.Xor(tag, S);

            int resultLen = extra;

            // We place into macBlock our calculated value for T
            this.macBlock = new byte[macSize];
            Array.Copy(tag, 0, macBlock, 0, macSize);

            if (forEncryption)
            {
                // Append T to the message
                Array.Copy(macBlock, 0, output, outOff + bufOff, macSize);
                resultLen += macSize;
            }
            else
            {
                // Retrieve the T value from the message and compare to calculated one
                byte[] msgMac = new byte[macSize];
                Array.Copy(bufBlock, extra, msgMac, 0, macSize);
                if (!Arrays.ConstantTimeAreEqual(this.macBlock, msgMac))
                {
                    throw new InvalidCipherTextException("mac check in GCM failed");
                }
            }

            Reset(false);

            return(resultLen);
        }
 public void MultiplyH(byte[] x)
 {
     GcmUtilities.Multiply(x, H);
 }
Example #7
0
        public int DoFinal(byte[] output, int outOff)
        {
            if (this.totalLength == 0L)
            {
                this.InitCipher();
            }
            int bufOff = this.bufOff;

            if (this.forEncryption)
            {
                Check.OutputLength(output, outOff, bufOff + this.macSize, "Output buffer too short");
            }
            else
            {
                if (bufOff < this.macSize)
                {
                    throw new InvalidCipherTextException("data too short");
                }
                bufOff -= this.macSize;
                Check.OutputLength(output, outOff, bufOff, "Output buffer too short");
            }
            if (bufOff > 0)
            {
                this.gCTRPartial(this.bufBlock, 0, bufOff, output, outOff);
            }
            this.atLength += (ulong)this.atBlockPos;
            if (this.atLength > this.atLengthPre)
            {
                if (this.atBlockPos > 0)
                {
                    this.gHASHPartial(this.S_at, this.atBlock, 0, this.atBlockPos);
                }
                if (this.atLengthPre > 0L)
                {
                    GcmUtilities.Xor(this.S_at, this.S_atPre);
                }
                long   pow    = (long)(((this.totalLength * 8L) + 0x7fL) >> 7);
                byte[] buffer = new byte[0x10];
                if (this.exp == null)
                {
                    this.exp = new Tables1kGcmExponentiator();
                    this.exp.Init(this.H);
                }
                this.exp.ExponentiateX(pow, buffer);
                GcmUtilities.Multiply(this.S_at, buffer);
                GcmUtilities.Xor(this.S, this.S_at);
            }
            byte[] bs = new byte[0x10];
            Pack.UInt64_To_BE((ulong)(this.atLength * ((ulong)8L)), bs, 0);
            Pack.UInt64_To_BE((ulong)(this.totalLength * ((ulong)8L)), bs, 8);
            this.gHASHBlock(this.S, bs);
            byte[] outBuf = new byte[0x10];
            this.cipher.ProcessBlock(this.J0, 0, outBuf, 0);
            GcmUtilities.Xor(outBuf, this.S);
            int num3 = bufOff;

            this.macBlock = new byte[this.macSize];
            Array.Copy(outBuf, 0, this.macBlock, 0, this.macSize);
            if (this.forEncryption)
            {
                Array.Copy(this.macBlock, 0, output, outOff + this.bufOff, this.macSize);
                num3 += this.macSize;
            }
            else
            {
                byte[] destinationArray = new byte[this.macSize];
                Array.Copy(this.bufBlock, bufOff, destinationArray, 0, this.macSize);
                if (!Arrays.ConstantTimeAreEqual(this.macBlock, destinationArray))
                {
                    throw new InvalidCipherTextException("mac check in GCM failed");
                }
            }
            this.Reset(false);
            return(num3);
        }