private void gCTRPartial(byte[] buf, int off, int len, byte[] output, int outOff) { byte[] tmp = GetNextCounterBlock(); GcmUtilities.Xor(tmp, buf, off, len); Array.Copy(tmp, 0, output, outOff, len); gHASHPartial(S, forEncryption ? tmp : buf, 0, len); totalLength += (uint)len; }
private void gCTRBlock(byte[] block, byte[] output, int outOff) { byte[] tmp = GetNextCounterBlock(); GcmUtilities.Xor(tmp, block); Array.Copy(tmp, 0, output, outOff, BlockSize); gHASHBlock(S, forEncryption ? tmp : block); totalLength += BlockSize; }
private byte[] gHASH(byte[] b) { byte[] array = new byte[16]; for (int i = 0; i < b.Length; i += 16) { byte[] array2 = new byte[16]; int length = Math.Min(b.Length - i, 16); Array.Copy(b, i, array2, 0, length); GcmUtilities.Xor(array, array2); multiplier.MultiplyH(array); } return(array); }
private byte[] gHASH(byte[] b) { byte[] numArray = new byte[16]; for (int sourceIndex = 0; sourceIndex < b.Length; sourceIndex += 16) { byte[] val = new byte[16]; int length = Math.Min(b.Length - sourceIndex, 16); Array.Copy((Array)b, sourceIndex, (Array)val, 0, length); GcmUtilities.Xor(numArray, val); this.multiplier.MultiplyH(numArray); } return(numArray); }
private byte[] gHASH(byte[] b) { byte[] Y = new byte[16]; for (int pos = 0; pos < b.Length; pos += 16) { byte[] X = new byte[16]; int num = System.Math.Min(b.Length - pos, 16); Array.Copy(b, pos, X, 0, num); GcmUtilities.Xor(Y, X); multiplier.MultiplyH(Y); } return(Y); }
public void Init(byte[] H) { if (M == null) { M = new uint[16][][]; } else if (Arrays.AreEqual(this.H, H)) { return; } this.H = Arrays.Clone(H); M[0] = new uint[256][]; M[0][0] = new uint[4]; M[0][128] = GcmUtilities.AsUints(H); for (int num = 64; num >= 1; num >>= 1) { uint[] array = (uint[])M[0][num + num].Clone(); GcmUtilities.MultiplyP(array); M[0][num] = array; } int num2 = 0; while (true) { for (int i = 2; i < 256; i += i) { for (int j = 1; j < i; j++) { uint[] array2 = (uint[])M[num2][i].Clone(); GcmUtilities.Xor(array2, M[num2][j]); M[num2][i + j] = array2; } } if (++num2 == 16) { break; } M[num2] = new uint[256][]; M[num2][0] = new uint[4]; for (int num3 = 128; num3 > 0; num3 >>= 1) { uint[] array3 = (uint[])M[num2 - 1][num3].Clone(); GcmUtilities.MultiplyP8(array3); M[num2][num3] = array3; } } }
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); }
public int DoFinal(byte[] output, int outOff) { int num = bufOff; if (!forEncryption) { if (num < macSize) { throw new InvalidCipherTextException("data too short"); } num -= macSize; } if (num > 0) { byte[] array = new byte[16]; Array.Copy(bufBlock, 0, array, 0, num); gCTRBlock(array, num, output, outOff); } byte[] array2 = new byte[16]; packLength((ulong)((long)A.Length * 8L), array2, 0); packLength(totalLength * 8, array2, 8); GcmUtilities.Xor(S, array2); multiplier.MultiplyH(S); byte[] array3 = new byte[16]; cipher.ProcessBlock(J0, 0, array3, 0); GcmUtilities.Xor(array3, S); int num2 = num; macBlock = new byte[macSize]; Array.Copy(array3, 0, macBlock, 0, macSize); if (forEncryption) { Array.Copy(macBlock, 0, output, outOff + bufOff, macSize); num2 += macSize; } else { byte[] array4 = new byte[macSize]; Array.Copy(bufBlock, num, array4, 0, macSize); if (!Arrays.ConstantTimeAreEqual(macBlock, array4)) { throw new InvalidCipherTextException("mac check in GCM failed"); } } Reset(clearMac: false); return(num2); }
// Token: 0x060000ED RID: 237 RVA: 0x000086C8 File Offset: 0x000068C8 private void ProcessPartial(byte[] buf, int off, int len, byte[] output, int outOff) { byte[] array = new byte[16]; this.GetNextCtrBlock(array); if (this.forEncryption) { GcmUtilities.Xor(buf, off, array, 0, len); this.gHASHPartial(this.S, buf, off, len); } else { this.gHASHPartial(this.S, buf, off, len); GcmUtilities.Xor(buf, off, array, 0, len); } Array.Copy(buf, off, output, outOff, len); this.totalLength += (ulong)len; }
private void ProcessPartial(byte[] buf, int off, int len, byte[] output, int outOff) { byte[] ctrBlock = new byte[BlockSize]; GetNextCtrBlock(ctrBlock); if (forEncryption) { GcmUtilities.Xor(buf, off, ctrBlock, 0, len); gHASHPartial(S, buf, off, len); } else { gHASHPartial(S, buf, off, len); GcmUtilities.Xor(buf, off, ctrBlock, 0, len); } Array.Copy(buf, off, output, outOff, len); totalLength += (uint)len; }
// Token: 0x060000EC RID: 236 RVA: 0x00008638 File Offset: 0x00006838 private void ProcessBlock(byte[] buf, int bufOff, byte[] output, int outOff) { Check.OutputLength(output, outOff, 16, "Output buffer too short"); if (this.totalLength == 0UL) { this.InitCipher(); } byte[] array = new byte[16]; this.GetNextCtrBlock(array); if (this.forEncryption) { GcmUtilities.Xor(array, buf, bufOff); this.gHASHBlock(this.S, array); Array.Copy(array, 0, output, outOff, 16); } else { this.gHASHBlock(this.S, buf, bufOff); GcmUtilities.Xor(array, 0, buf, bufOff, output, outOff); } this.totalLength += 16UL; }
private void gCTRBlock(byte[] buf, int bufCount, byte[] output, int outOff) { // inc(counter); for (int i = 15; i >= 12; --i) { if (++counter[i] != 0) { break; } } byte[] tmp = new byte[BlockSize]; cipher.ProcessBlock(counter, 0, tmp, 0); byte[] hashBytes; if (forEncryption) { Array.Copy(Zeroes, bufCount, tmp, bufCount, BlockSize - bufCount); hashBytes = tmp; } else { hashBytes = buf; } for (int i = bufCount - 1; i >= 0; --i) { tmp[i] ^= buf[i]; output[outOff + i] = tmp[i]; } // gHASHBlock(hashBytes); GcmUtilities.Xor(S, hashBytes); multiplier.MultiplyH(S); totalLength += (ulong)bufCount; }
private void gHASHPartial(byte[] Y, byte[] b, int off, int len) { GcmUtilities.Xor(Y, b, off, len); multiplier.MultiplyH(Y); }
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); }
private void gHASHBlock(byte[] Y, byte[] b) { GcmUtilities.Xor(Y, b); multiplier.MultiplyH(Y); }
public virtual void Init(bool forEncryption, ICipherParameters parameters) { this.forEncryption = forEncryption; macBlock = null; if (parameters is AeadParameters) { AeadParameters aeadParameters = (AeadParameters)parameters; nonce = aeadParameters.GetNonce(); A = aeadParameters.GetAssociatedText(); int num = aeadParameters.MacSize; if (num < 96 || num > 128 || num % 8 != 0) { throw new ArgumentException("Invalid value for MAC size: " + num); } macSize = num / 8; keyParam = aeadParameters.Key; } else { if (!(parameters is ParametersWithIV)) { throw new ArgumentException("invalid parameters passed to GCM"); } ParametersWithIV parametersWithIV = (ParametersWithIV)parameters; nonce = parametersWithIV.GetIV(); A = null; macSize = 16; keyParam = (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 (A == null) { A = new byte[0]; } cipher.Init(forEncryption: true, keyParam); H = new byte[16]; cipher.ProcessBlock(H, 0, H, 0); multiplier.Init(H); initS = gHASH(A); if (nonce.Length == 12) { J0 = new byte[16]; Array.Copy(nonce, 0, J0, 0, nonce.Length); J0[15] = 1; } else { J0 = gHASH(nonce); byte[] array = new byte[16]; packLength((ulong)((long)nonce.Length * 8L), array, 8); GcmUtilities.Xor(J0, array); multiplier.MultiplyH(J0); } S = Arrays.Clone(initS); counter = Arrays.Clone(J0); bufOff = 0; totalLength = 0uL; }
// Token: 0x060000F0 RID: 240 RVA: 0x00008780 File Offset: 0x00006980 private void gHASHBlock(byte[] Y, byte[] b, int off) { GcmUtilities.Xor(Y, b, off); this.multiplier.MultiplyH(Y); }
// 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); }
public void Init(byte[] H) { if (M == null) { M = new uint[32][][]; } else if (Arrays.AreEqual(this.H, H)) { return; } this.H = Arrays.Clone(H); M[0] = new uint[16][]; M[1] = new uint[16][]; M[0][0] = new uint[4]; M[1][0] = new uint[4]; M[1][8] = GcmUtilities.AsUints(H); for (int num = 4; num >= 1; num >>= 1) { uint[] array = (uint[])M[1][num + num].Clone(); GcmUtilities.MultiplyP(array); M[1][num] = array; } uint[] array2 = (uint[])M[1][1].Clone(); GcmUtilities.MultiplyP(array2); M[0][8] = array2; for (int num2 = 4; num2 >= 1; num2 >>= 1) { uint[] array3 = (uint[])M[0][num2 + num2].Clone(); GcmUtilities.MultiplyP(array3); M[0][num2] = array3; } int num3 = 0; while (true) { for (int i = 2; i < 16; i += i) { for (int j = 1; j < i; j++) { uint[] array4 = (uint[])M[num3][i].Clone(); GcmUtilities.Xor(array4, M[num3][j]); M[num3][i + j] = array4; } } if (++num3 == 32) { break; } if (num3 > 1) { M[num3] = new uint[16][]; M[num3][0] = new uint[4]; for (int num4 = 8; num4 > 0; num4 >>= 1) { uint[] array5 = (uint[])M[num3 - 2][num4].Clone(); GcmUtilities.MultiplyP8(array5); M[num3][num4] = array5; } } } }
private void gHASHBlock(byte[] Y, byte[] b, int off) { GcmUtilities.Xor(Y, b, off); Tables8kGcmMultiplier_MultiplyH(Y); }
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; }
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) { this.forEncryption = forEncryption; this.macBlock = null; if (parameters is AeadParameters) { AeadParameters param = (AeadParameters)parameters; nonce = param.GetNonce(); A = param.GetAssociatedText(); int macSizeBits = param.MacSize; if (macSizeBits < 96 || 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(); A = 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"); } if (A == null) { // Avoid lots of null checks A = new byte[0]; } // Cipher always used in forward mode cipher.Init(true, keyParam); // TODO This should be configurable by Init parameters // (but must be 16 if nonce length not 12) (BlockSize?) // this.tagLength = 16; this.H = new byte[BlockSize]; cipher.ProcessBlock(H, 0, H, 0); multiplier.Init(H); this.initS = gHASH(A); if (nonce.Length == 12) { this.J0 = new byte[16]; Array.Copy(nonce, 0, J0, 0, nonce.Length); this.J0[15] = 0x01; } else { this.J0 = gHASH(nonce); byte[] X = new byte[16]; packLength((ulong)nonce.Length * 8UL, X, 8); GcmUtilities.Xor(this.J0, X); multiplier.MultiplyH(this.J0); } this.S = Arrays.Clone(initS); this.counter = Arrays.Clone(J0); this.bufOff = 0; this.totalLength = 0; }
public void Tables8kGcmMultiplier_Init(byte[] H) { if (Tables8kGcmMultiplier_M == null) { Tables8kGcmMultiplier_M = new uint[32][][]; } else if (Arrays.AreEqual(this.Tables8kGcmMultiplier_H, H)) { return; } this.Tables8kGcmMultiplier_H = Arrays.Clone(H); Tables8kGcmMultiplier_M[0] = new uint[16][]; Tables8kGcmMultiplier_M[1] = new uint[16][]; Tables8kGcmMultiplier_M[0][0] = new uint[4]; Tables8kGcmMultiplier_M[1][0] = new uint[4]; Tables8kGcmMultiplier_M[1][8] = GcmUtilities.AsUints(H); for (int j = 4; j >= 1; j >>= 1) { uint[] tmp = (uint[])Tables8kGcmMultiplier_M[1][j + j].Clone(); GcmUtilities.MultiplyP(tmp); Tables8kGcmMultiplier_M[1][j] = tmp; } { uint[] tmp = (uint[])Tables8kGcmMultiplier_M[1][1].Clone(); GcmUtilities.MultiplyP(tmp); Tables8kGcmMultiplier_M[0][8] = tmp; } for (int j = 4; j >= 1; j >>= 1) { uint[] tmp = (uint[])Tables8kGcmMultiplier_M[0][j + j].Clone(); GcmUtilities.MultiplyP(tmp); Tables8kGcmMultiplier_M[0][j] = tmp; } for (int i = 0; ;) { for (int j = 2; j < 16; j += j) { for (int k = 1; k < j; ++k) { uint[] tmp = (uint[])Tables8kGcmMultiplier_M[i][j].Clone(); GcmUtilities.Xor(tmp, Tables8kGcmMultiplier_M[i][k]); Tables8kGcmMultiplier_M[i][j + k] = tmp; } } if (++i == 32) { return; } if (i > 1) { Tables8kGcmMultiplier_M[i] = new uint[16][]; Tables8kGcmMultiplier_M[i][0] = new uint[4]; for (int j = 8; j > 0; j >>= 1) { uint[] tmp = (uint[])Tables8kGcmMultiplier_M[i - 2][j].Clone(); GcmUtilities.MultiplyP8(tmp); Tables8kGcmMultiplier_M[i][j] = tmp; } } } }
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) { int extra = bufOff; if (!forEncryption) { if (extra < macSize) { throw new InvalidCipherTextException("data too short"); } extra -= macSize; } if (extra > 0) { byte[] tmp = new byte[BlockSize]; Array.Copy(bufBlock, 0, tmp, 0, extra); gCTRBlock(tmp, extra, output, outOff); } // Final gHASH byte[] X = new byte[16]; packLength((ulong)A.Length * 8UL, X, 0); packLength(totalLength * 8UL, X, 8); GcmUtilities.Xor(S, X); multiplier.MultiplyH(S); // TODO Fix this if tagLength becomes configurable // 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); }