diff --git a/crypto/src/crypto/modes/GCMBlockCipher.cs b/crypto/src/crypto/modes/GCMBlockCipher.cs
index 74b895e7b..91858f6f5 100644
--- a/crypto/src/crypto/modes/GCMBlockCipher.cs
+++ b/crypto/src/crypto/modes/GCMBlockCipher.cs
@@ -8,123 +8,123 @@ using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Modes
{
- /// <summary>
- /// Implements the Galois/Counter mode (GCM) detailed in
- /// NIST Special Publication 800-38D.
- /// </summary>
- public class GcmBlockCipher
- : IAeadBlockCipher
- {
- private const int BlockSize = 16;
+ /// <summary>
+ /// Implements the Galois/Counter mode (GCM) detailed in
+ /// NIST Special Publication 800-38D.
+ /// </summary>
+ public class GcmBlockCipher
+ : IAeadBlockCipher
+ {
+ private const int BlockSize = 16;
private readonly IBlockCipher cipher;
- private readonly IGcmMultiplier multiplier;
+ private readonly IGcmMultiplier multiplier;
private IGcmExponentiator exp;
// These fields are set by Init and not modified by processing
- private bool forEncryption;
- private int macSize;
- private byte[] nonce;
- private byte[] initialAssociatedText;
+ private bool forEncryption;
+ private int macSize;
+ private byte[] nonce;
+ private byte[] initialAssociatedText;
private byte[] H;
- private byte[] J0;
+ private byte[] J0;
// These fields are modified during processing
- private byte[] bufBlock;
- private byte[] macBlock;
+ private byte[] bufBlock;
+ private byte[] macBlock;
private byte[] S, S_at, S_atPre;
- private byte[] counter;
- private int bufOff;
- private ulong totalLength;
+ private byte[] counter;
+ private int bufOff;
+ private ulong totalLength;
private byte[] atBlock;
private int atBlockPos;
private ulong atLength;
private ulong atLengthPre;
public GcmBlockCipher(
- IBlockCipher c)
- : this(c, null)
- {
- }
-
- public GcmBlockCipher(
- IBlockCipher c,
- IGcmMultiplier m)
- {
- if (c.GetBlockSize() != BlockSize)
- throw new ArgumentException("cipher required with a block size of " + BlockSize + ".");
-
- if (m == null)
- {
- // TODO Consider a static property specifying default multiplier
- m = new Tables8kGcmMultiplier();
- }
-
- this.cipher = c;
- this.multiplier = m;
- }
-
- public virtual string AlgorithmName
- {
- get { return cipher.AlgorithmName + "/GCM"; }
- }
-
- public IBlockCipher GetUnderlyingCipher()
- {
- return cipher;
- }
-
- public virtual int GetBlockSize()
- {
- return BlockSize;
- }
-
- public virtual void Init(
- bool forEncryption,
- ICipherParameters parameters)
- {
- this.forEncryption = forEncryption;
- this.macBlock = null;
+ IBlockCipher c)
+ : this(c, null)
+ {
+ }
+
+ public GcmBlockCipher(
+ IBlockCipher c,
+ IGcmMultiplier m)
+ {
+ if (c.GetBlockSize() != BlockSize)
+ throw new ArgumentException("cipher required with a block size of " + BlockSize + ".");
+
+ if (m == null)
+ {
+ // TODO Consider a static property specifying default multiplier
+ m = new Tables8kGcmMultiplier();
+ }
+
+ this.cipher = c;
+ this.multiplier = m;
+ }
+
+ public virtual string AlgorithmName
+ {
+ get { return cipher.AlgorithmName + "/GCM"; }
+ }
+
+ public IBlockCipher GetUnderlyingCipher()
+ {
+ return cipher;
+ }
+
+ public virtual int GetBlockSize()
+ {
+ return BlockSize;
+ }
+
+ 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 < 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();
+ {
+ AeadParameters param = (AeadParameters)parameters;
+
+ nonce = param.GetNonce();
+ initialAssociatedText = 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();
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");
- }
+ 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 This should be configurable by Init parameters
// (but must be 16 if nonce length not 12) (BlockSize?)
@@ -136,8 +136,8 @@ namespace Org.BouncyCastle.Crypto.Modes
{
cipher.Init(true, keyParam);
- this.H = new byte[BlockSize];
- cipher.ProcessBlock(H, 0, H, 0);
+ 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);
@@ -147,17 +147,17 @@ namespace Org.BouncyCastle.Crypto.Modes
this.J0 = new byte[BlockSize];
if (nonce.Length == 12)
- {
- Array.Copy(nonce, 0, J0, 0, nonce.Length);
- this.J0[BlockSize - 1] = 0x01;
- }
- else
- {
+ {
+ Array.Copy(nonce, 0, J0, 0, nonce.Length);
+ this.J0[BlockSize - 1] = 0x01;
+ }
+ else
+ {
gHASH(J0, nonce, nonce.Length);
- byte[] X = new byte[BlockSize];
+ 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];
@@ -174,16 +174,16 @@ namespace Org.BouncyCastle.Crypto.Modes
{
ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length);
}
- }
+ }
- public virtual byte[] GetMac()
- {
- return Arrays.Clone(macBlock);
- }
+ public virtual byte[] GetMac()
+ {
+ return Arrays.Clone(macBlock);
+ }
- public virtual int GetOutputSize(
- int len)
- {
+ public virtual int GetOutputSize(
+ int len)
+ {
int totalData = len + bufOff;
if (forEncryption)
@@ -192,11 +192,11 @@ namespace Org.BouncyCastle.Crypto.Modes
}
return totalData < macSize ? 0 : totalData - macSize;
- }
+ }
public virtual int GetUpdateOutputSize(
- int len)
- {
+ int len)
+ {
int totalData = len + bufOff;
if (!forEncryption)
{
@@ -207,7 +207,7 @@ namespace Org.BouncyCastle.Crypto.Modes
totalData -= macSize;
}
return totalData - totalData % BlockSize;
- }
+ }
public virtual void ProcessAadByte(byte input)
{
@@ -258,10 +258,10 @@ namespace Org.BouncyCastle.Crypto.Modes
}
public virtual int ProcessByte(
- byte input,
- byte[] output,
- int outOff)
- {
+ byte input,
+ byte[] output,
+ int outOff)
+ {
bufBlock[bufOff] = input;
if (++bufOff == bufBlock.Length)
{
@@ -269,15 +269,15 @@ namespace Org.BouncyCastle.Crypto.Modes
return BlockSize;
}
return 0;
- }
+ }
public virtual int ProcessBytes(
- byte[] input,
- int inOff,
- int len,
- byte[] output,
- int outOff)
- {
+ byte[] input,
+ int inOff,
+ int len,
+ byte[] output,
+ int outOff)
+ {
int resultLen = 0;
for (int i = 0; i < len; ++i)
@@ -291,7 +291,7 @@ namespace Org.BouncyCastle.Crypto.Modes
}
return resultLen;
- }
+ }
private void OutputBlock(byte[] output, int offset)
{
@@ -311,8 +311,8 @@ namespace Org.BouncyCastle.Crypto.Modes
}
}
- public int DoFinal(byte[] output, int outOff)
- {
+ public int DoFinal(byte[] output, int outOff)
+ {
if (totalLength == 0)
{
InitCipher();
@@ -375,52 +375,52 @@ namespace Org.BouncyCastle.Crypto.Modes
}
// Final gHASH
- byte[] X = new byte[BlockSize];
+ byte[] X = new byte[BlockSize];
Pack.UInt64_To_BE(atLength * 8UL, X, 0);
Pack.UInt64_To_BE(totalLength * 8UL, X, 8);
gHASHBlock(S, X);
- // 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;
- }
-
- public virtual void Reset()
- {
- Reset(true);
- }
-
- private void Reset(
- bool clearMac)
- {
+ // 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;
+ }
+
+ public virtual void Reset()
+ {
+ Reset(true);
+ }
+
+ private void Reset(
+ bool clearMac)
+ {
cipher.Reset();
S = new byte[BlockSize];
@@ -448,7 +448,7 @@ namespace Org.BouncyCastle.Crypto.Modes
{
ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length);
}
- }
+ }
private void gCTRBlock(byte[] block, byte[] output, int outOff)
{
@@ -507,5 +507,5 @@ namespace Org.BouncyCastle.Crypto.Modes
cipher.ProcessBlock(counter, 0, tmp, 0);
return tmp;
}
- }
+ }
}
|