public virtual void Init(bool forEncryption, ICipherParameters parameters) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) this.forEncryption = forEncryption; macBlock = null; KeyParameter keyParameter; if (parameters is AeadParameters) { AeadParameters aeadParameters = (AeadParameters)parameters; nonce = aeadParameters.GetNonce(); initialAssociatedText = aeadParameters.GetAssociatedText(); int num = aeadParameters.MacSize; if (num < 32 || num > 128 || num % 8 != 0) { throw new ArgumentException(string.Concat((object)"Invalid value for MAC size: ", (object)num)); } macSize = num / 8; keyParameter = aeadParameters.Key; } else { if (!(parameters is ParametersWithIV)) { throw new ArgumentException("invalid parameters passed to GCM"); } ParametersWithIV parametersWithIV = (ParametersWithIV)parameters; nonce = parametersWithIV.GetIV(); initialAssociatedText = null; macSize = 16; keyParameter = (KeyParameter)parametersWithIV.Parameters; } int num2 = (forEncryption ? 16 : (16 + macSize)); bufBlock = new byte[num2]; if (nonce == null || nonce.Length < 1) { throw new ArgumentException("IV must be at least 1 byte"); } if (keyParameter != null) { cipher.Init(forEncryption: true, keyParameter); H = new byte[16]; cipher.ProcessBlock(H, 0, H, 0); multiplier.Init(H); exp = null; } else if (H == null) { throw new ArgumentException("Key must be specified in initial init"); } J0 = new byte[16]; if (nonce.Length == 12) { global::System.Array.Copy((global::System.Array)nonce, 0, (global::System.Array)J0, 0, nonce.Length); J0[15] = 1; } else { gHASH(J0, nonce, nonce.Length); byte[] array = new byte[16]; Pack.UInt64_To_BE((ulong)nonce.Length * 8uL, array, 8); gHASHBlock(J0, array); } S = new byte[16]; S_at = new byte[16]; S_atPre = new byte[16]; atBlock = new byte[16]; atBlockPos = 0; atLength = 0uL; atLengthPre = 0uL; counter = Arrays.Clone(J0); bufOff = 0; totalLength = 0uL; if (initialAssociatedText != null) { ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); } }
/// <remarks> /// MAC sizes from 32 bits to 128 bits (must be a multiple of 8) are supported. The default is 128 bits. /// Sizes less than 96 are not recommended, but are supported for specialized applications. /// </remarks> public virtual void Init( bool forEncryption, ICipherParameters parameters) { this.forEncryption = forEncryption; this.macBlock = null; KeyParameter keyParam; if (parameters is AeadParameters) { AeadParameters param = (AeadParameters)parameters; nonce = param.GetNonce(); initialAssociatedText = param.GetAssociatedText(); int macSizeBits = param.MacSize; if (macSizeBits < 32 || macSizeBits > 128 || macSizeBits % 8 != 0) { throw new ArgumentException("Invalid value for MAC size: " + macSizeBits); } macSize = macSizeBits / 8; keyParam = param.Key; } else if (parameters is ParametersWithIV) { ParametersWithIV param = (ParametersWithIV)parameters; nonce = param.GetIV(); initialAssociatedText = null; macSize = 16; keyParam = (KeyParameter)param.Parameters; } else { throw new ArgumentException("invalid parameters passed to GCM"); } int bufLength = forEncryption ? BlockSize : (BlockSize + macSize); this.bufBlock = new byte[bufLength]; if (nonce == null || nonce.Length < 1) { throw new ArgumentException("IV must be at least 1 byte"); } // TODO Restrict macSize to 16 if nonce length not 12? // Cipher always used in forward mode // if keyParam is null we're reusing the last key. if (keyParam != null) { cipher.Init(true, keyParam); this.H = new byte[BlockSize]; cipher.ProcessBlock(H, 0, H, 0); // if keyParam is null we're reusing the last key and the multiplier doesn't need re-init multiplier.Init(H); exp = null; } else if (this.H == null) { throw new ArgumentException("Key must be specified in initial init"); } this.J0 = new byte[BlockSize]; if (nonce.Length == 12) { Array.Copy(nonce, 0, J0, 0, nonce.Length); this.J0[BlockSize - 1] = 0x01; } else { gHASH(J0, nonce, nonce.Length); byte[] X = new byte[BlockSize]; Pack.UInt64_To_BE((ulong)nonce.Length * 8UL, X, 8); gHASHBlock(J0, X); } this.S = new byte[BlockSize]; this.S_at = new byte[BlockSize]; this.S_atPre = new byte[BlockSize]; this.atBlock = new byte[BlockSize]; this.atBlockPos = 0; this.atLength = 0; this.atLengthPre = 0; this.counter = Arrays.Clone(J0); this.bufOff = 0; this.totalLength = 0; if (initialAssociatedText != null) { ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); } }
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); }
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 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); }
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 virtual void Init(bool forEncryption, ICipherParameters parameters) { KeyParameter key; this.forEncryption = forEncryption; this.macBlock = null; if (parameters is AeadParameters) { AeadParameters parameters2 = (AeadParameters)parameters; this.nonce = parameters2.GetNonce(); this.initialAssociatedText = parameters2.GetAssociatedText(); int macSize = parameters2.MacSize; if (((macSize < 0x20) || (macSize > 0x80)) || ((macSize % 8) != 0)) { throw new ArgumentException("Invalid value for MAC size: " + macSize); } this.macSize = macSize / 8; key = parameters2.Key; } else { if (!(parameters is ParametersWithIV)) { throw new ArgumentException("invalid parameters passed to GCM"); } ParametersWithIV hiv = (ParametersWithIV)parameters; this.nonce = hiv.GetIV(); this.initialAssociatedText = null; this.macSize = 0x10; key = (KeyParameter)hiv.Parameters; } int num2 = !forEncryption ? (0x10 + this.macSize) : 0x10; this.bufBlock = new byte[num2]; if ((this.nonce == null) || (this.nonce.Length < 1)) { throw new ArgumentException("IV must be at least 1 byte"); } if (key != null) { this.cipher.Init(true, key); this.H = new byte[0x10]; this.cipher.ProcessBlock(this.H, 0, this.H, 0); this.multiplier.Init(this.H); this.exp = null; } else if (this.H == null) { throw new ArgumentException("Key must be specified in initial init"); } this.J0 = new byte[0x10]; if (this.nonce.Length == 12) { Array.Copy(this.nonce, 0, this.J0, 0, this.nonce.Length); this.J0[15] = 1; } else { this.gHASH(this.J0, this.nonce, this.nonce.Length); byte[] bs = new byte[0x10]; Pack.UInt64_To_BE((ulong)(this.nonce.Length * 8L), bs, 8); this.gHASHBlock(this.J0, bs); } this.S = new byte[0x10]; this.S_at = new byte[0x10]; this.S_atPre = new byte[0x10]; this.atBlock = new byte[0x10]; this.atBlockPos = 0; this.atLength = 0L; this.atLengthPre = 0L; this.counter = Arrays.Clone(this.J0); this.blocksRemaining = 0xfffffffe; this.bufOff = 0; this.totalLength = 0L; if (this.initialAssociatedText != null) { this.ProcessAadBytes(this.initialAssociatedText, 0, this.initialAssociatedText.Length); } }
/// <remarks> /// MAC sizes from 32 bits to 128 bits (must be a multiple of 8) are supported. The default is 128 bits. /// Sizes less than 96 are not recommended, but are supported for specialized applications. /// </remarks> public /*virtual*/ void Init( bool forEncryption, ICipherParameters parameters) { this.forEncryption = forEncryption; //this.macBlock = null; if (this.macBlock != null) { Array.Clear(this.macBlock, 0, this.macBlock.Length); } this.initialised = true; KeyParameter keyParam; byte[] newNonce = null; if (parameters is AeadParameters) { AeadParameters param = (AeadParameters)parameters; newNonce = param.GetNonce(); initialAssociatedText = param.GetAssociatedText(); int macSizeBits = param.MacSize; if (macSizeBits < 32 || macSizeBits > 128 || macSizeBits % 8 != 0) { throw new ArgumentException("Invalid value for MAC size: " + macSizeBits); } macSize = macSizeBits / 8; keyParam = param.Key; } else if (parameters is ParametersWithIV) { ParametersWithIV param = (ParametersWithIV)parameters; newNonce = param.GetIV(); initialAssociatedText = null; macSize = 16; keyParam = (KeyParameter)param.Parameters; } else { throw new ArgumentException("invalid parameters passed to GCM"); } this.bufLength = forEncryption ? BlockSize : (BlockSize + macSize); if (this.bufBlock == null || this.bufLength < this.bufBlock.Length) { BufferPool.Resize(ref this.bufBlock, this.bufLength, true, true); } if (newNonce == null || newNonce.Length < 1) { throw new ArgumentException("IV must be at least 1 byte"); } if (forEncryption) { if (nonce != null && Arrays.AreEqual(nonce, newNonce)) { if (keyParam == null) { throw new ArgumentException("cannot reuse nonce for GCM encryption"); } if (lastKey != null && Arrays.AreEqual(lastKey, keyParam.GetKey())) { throw new ArgumentException("cannot reuse nonce for GCM encryption"); } } } nonce = newNonce; if (keyParam != null) { lastKey = keyParam.GetKey(); } // TODO Restrict macSize to 16 if nonce length not 12? // Cipher always used in forward mode // if keyParam is null we're reusing the last key. if (keyParam != null) { cipher.Init(true, keyParam); if (this.H == null) { this.H = new byte[BlockSize]; } else { Array.Clear(this.H, 0, BlockSize); } cipher.ProcessBlock(H, 0, H, 0); // if keyParam is null we're reusing the last key and the multiplier doesn't need re-init Tables8kGcmMultiplier_Init(H); exp = null; } else if (this.H == null) { throw new ArgumentException("Key must be specified in initial init"); } if (this.J0 == null) { this.J0 = new byte[BlockSize]; } else { Array.Clear(this.J0, 0, BlockSize); } if (nonce.Length == 12) { Array.Copy(nonce, 0, J0, 0, nonce.Length); this.J0[BlockSize - 1] = 0x01; } else { gHASH(J0, nonce, nonce.Length); byte[] X = BufferPool.Get(BlockSize, false); Pack.UInt64_To_BE((ulong)nonce.Length * 8UL, X, 8); gHASHBlock(J0, X); BufferPool.Release(X); } //BufferPool.Resize(ref this.S, BlockSize, false, true); //BufferPool.Resize(ref this.S_at, BlockSize, false, true); //BufferPool.Resize(ref this.S_atPre, BlockSize, false, true); //BufferPool.Resize(ref this.atBlock, BlockSize, false, true); if (this.S == null) { this.S = new byte[BlockSize]; } else { Array.Clear(this.S, 0, this.S.Length); } if (this.S_at == null) { this.S_at = new byte[BlockSize]; } else { Array.Clear(this.S_at, 0, this.S_at.Length); } if (this.S_atPre == null) { this.S_atPre = new byte[BlockSize]; } else { Array.Clear(this.S_atPre, 0, this.S_atPre.Length); } if (this.atBlock == null) { this.atBlock = new byte[BlockSize]; } else { Array.Clear(this.atBlock, 0, this.atBlock.Length); } this.atBlockPos = 0; this.atLength = 0; this.atLengthPre = 0; //this.counter = Arrays.Clone(J0); //BufferPool.Resize(ref this.counter, BlockSize, false, true); if (this.counter == null) { this.counter = new byte[BlockSize]; } else { Array.Clear(this.counter, 0, this.counter.Length); } Array.Copy(this.J0, 0, this.counter, 0, BlockSize); this.blocksRemaining = uint.MaxValue - 1; // page 8, len(P) <= 2^39 - 256, 1 block used by tag this.bufOff = 0; this.totalLength = 0; if (initialAssociatedText != null) { ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); } }
public virtual void Init(bool forEncryption, ICipherParameters parameters) { this.forEncryption = forEncryption; macBlock = null; KeyParameter keyParameter; if (parameters is AeadParameters) { AeadParameters aeadParameters = (AeadParameters)parameters; nonce = aeadParameters.GetNonce(); initialAssociatedText = aeadParameters.GetAssociatedText(); int num = aeadParameters.MacSize; if (num < 32 || num > 128 || num % 8 != 0) { throw new ArgumentException("Invalid value for MAC size: " + num); } macSize = num / 8; keyParameter = aeadParameters.Key; } else { if (!(parameters is ParametersWithIV)) { throw new ArgumentException("invalid parameters passed to GCM"); } ParametersWithIV parametersWithIV = (ParametersWithIV)parameters; nonce = parametersWithIV.GetIV(); initialAssociatedText = null; macSize = 16; keyParameter = (KeyParameter)parametersWithIV.Parameters; } int num2 = (!forEncryption) ? (16 + macSize) : 16; bufBlock = new byte[num2]; if (nonce == null || nonce.Length < 1) { throw new ArgumentException("IV must be at least 1 byte"); } if (keyParameter != null) { cipher.Init(forEncryption: true, keyParameter); H = new byte[16]; cipher.ProcessBlock(H, 0, H, 0); multiplier.Init(H); exp = null; } else if (H == null) { throw new ArgumentException("Key must be specified in initial init"); } J0 = new byte[16]; if (nonce.Length == 12) { Array.Copy(nonce, 0, J0, 0, nonce.Length); J0[15] = 1; } else { gHASH(J0, nonce, nonce.Length); byte[] array = new byte[16]; Pack.UInt64_To_BE((ulong)((long)nonce.Length * 8L), array, 8); gHASHBlock(J0, array); } S = new byte[16]; S_at = new byte[16]; S_atPre = new byte[16]; atBlock = new byte[16]; atBlockPos = 0; atLength = 0uL; atLengthPre = 0uL; counter = Arrays.Clone(J0); bufOff = 0; totalLength = 0uL; if (initialAssociatedText != null) { ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); } }
public virtual void Init(bool forEncryption, ICipherParameters parameters) { this.forEncryption = forEncryption; macBlock = null; initialised = true; byte[] array = null; if (parameters is AeadParameters) { AeadParameters aeadParameters = (AeadParameters)parameters; array = aeadParameters.GetNonce(); initialAssociatedText = aeadParameters.GetAssociatedText(); int num = aeadParameters.MacSize; if (num < 32 || num > 128 || num % 8 != 0) { throw new ArgumentException("Invalid value for MAC size: " + num); } macSize = num / 8; KeyParameter key = aeadParameters.Key; int num2 = forEncryption ? 16 : (16 + macSize); bufBlock = new byte[num2]; if (array == null || array.Length < 1) { throw new ArgumentException("IV must be at least 1 byte"); } if (forEncryption && nonce != null && Arrays.AreEqual(nonce, array)) { if (key == null) { throw new ArgumentException("cannot reuse nonce for GCM encryption"); } if (lastKey != null && Arrays.AreEqual(lastKey, key.GetKey())) { throw new ArgumentException("cannot reuse nonce for GCM encryption"); } } nonce = array; if (key != null) { lastKey = key.GetKey(); } if (key != null) { cipher.Init(forEncryption: true, key); H = new byte[16]; cipher.ProcessBlock(H, 0, H, 0); multiplier.Init(H); exp = null; } else if (H == null) { throw new ArgumentException("Key must be specified in initial init"); } J0 = new byte[16]; if (nonce.Length == 12) { Array.Copy(nonce, 0, J0, 0, nonce.Length); J0[15] = 1; } else { gHASH(J0, nonce, nonce.Length); byte[] array2 = new byte[16]; Pack.UInt64_To_BE((ulong)((long)nonce.Length * 8L), array2, 8); gHASHBlock(J0, array2); } S = new byte[16]; S_at = new byte[16]; S_atPre = new byte[16]; atBlock = new byte[16]; atBlockPos = 0; atLength = 0uL; atLengthPre = 0uL; counter = Arrays.Clone(J0); blocksRemaining = 4294967294u; bufOff = 0; totalLength = 0uL; if (initialAssociatedText != null) { ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); } return; } throw new ArgumentException("invalid parameters passed to GCM"); }
public int DoFinal(byte[] output, int outOff) { 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 InvalidCipherTextException("data too short"); } num -= this.macSize; Check.OutputLength(output, outOff, num, "Output buffer too short"); } if (num > 0) { this.gCTRPartial(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 InvalidCipherTextException("mac check in GCM failed"); } } this.Reset(false); return(num2); }