Example #1
0
        public int DoFinal(byte[] output, int outOff)
        {
            int bufOff = this.bufOff;

            if (!this.forEncryption)
            {
                if (bufOff < this.macSize)
                {
                    throw new InvalidCipherTextException("data too short");
                }
                bufOff -= this.macSize;
            }
            if (bufOff > 0)
            {
                byte[] buf = new byte[16];
                Array.Copy((Array)this.bufBlock, 0, (Array)buf, 0, bufOff);
                this.gCTRBlock(buf, bufOff, output, outOff);
            }
            byte[] numArray1 = new byte[16];
            GcmBlockCipher.packLength((ulong)this.A.Length * 8UL, numArray1, 0);
            GcmBlockCipher.packLength(this.totalLength * 8UL, numArray1, 8);
            GcmUtilities.Xor(this.S, numArray1);
            this.multiplier.MultiplyH(this.S);
            byte[] numArray2 = new byte[16];
            this.cipher.ProcessBlock(this.J0, 0, numArray2, 0);
            GcmUtilities.Xor(numArray2, this.S);
            int num = bufOff;

            this.macBlock = new byte[this.macSize];
            Array.Copy((Array)numArray2, 0, (Array)this.macBlock, 0, this.macSize);
            if (this.forEncryption)
            {
                Array.Copy((Array)this.macBlock, 0, (Array)output, outOff + this.bufOff, this.macSize);
                num += this.macSize;
            }
            else
            {
                byte[] b = new byte[this.macSize];
                Array.Copy((Array)this.bufBlock, bufOff, (Array)b, 0, this.macSize);
                if (!Arrays.ConstantTimeAreEqual(this.macBlock, b))
                {
                    throw new InvalidCipherTextException("mac check in GCM failed");
                }
            }
            this.Reset(false);
            return(num);
        }
Example #2
0
 public virtual void Init(bool forEncryption, ICipherParameters parameters)
 {
     this.forEncryption = forEncryption;
     this.macBlock      = (byte[])null;
     if (parameters is AeadParameters)
     {
         AeadParameters aeadParameters = (AeadParameters)parameters;
         this.nonce = aeadParameters.GetNonce();
         this.A     = aeadParameters.GetAssociatedText();
         int macSize = aeadParameters.MacSize;
         if (macSize < 96 || macSize > 128 || macSize % 8 != 0)
         {
             throw new ArgumentException("Invalid value for MAC size: " + (object)macSize);
         }
         this.macSize  = macSize / 8;
         this.keyParam = aeadParameters.Key;
     }
     else
     {
         if (!(parameters is ParametersWithIV))
         {
             throw new ArgumentException("invalid parameters passed to GCM");
         }
         ParametersWithIV parametersWithIv = (ParametersWithIV)parameters;
         this.nonce    = parametersWithIv.GetIV();
         this.A        = (byte[])null;
         this.macSize  = 16;
         this.keyParam = (KeyParameter)parametersWithIv.Parameters;
     }
     this.bufBlock = new byte[forEncryption ? 16 : 16 + this.macSize];
     if (this.nonce == null || this.nonce.Length < 1)
     {
         throw new ArgumentException("IV must be at least 1 byte");
     }
     if (this.A == null)
     {
         this.A = new byte[0];
     }
     this.cipher.Init(true, (ICipherParameters)this.keyParam);
     this.H = new byte[16];
     this.cipher.ProcessBlock(this.H, 0, this.H, 0);
     this.multiplier.Init(this.H);
     this.initS = this.gHASH(this.A);
     if (this.nonce.Length == 12)
     {
         this.J0 = new byte[16];
         Array.Copy((Array)this.nonce, 0, (Array)this.J0, 0, this.nonce.Length);
         this.J0[15] = (byte)1;
     }
     else
     {
         this.J0 = this.gHASH(this.nonce);
         byte[] numArray = new byte[16];
         GcmBlockCipher.packLength((ulong)this.nonce.Length * 8UL, numArray, 8);
         GcmUtilities.Xor(this.J0, numArray);
         this.multiplier.MultiplyH(this.J0);
     }
     this.S           = Arrays.Clone(this.initS);
     this.counter     = Arrays.Clone(this.J0);
     this.bufOff      = 0;
     this.totalLength = 0UL;
 }