summary refs log tree commit diff
path: root/crypto/src
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2014-07-21 13:07:18 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2014-07-21 13:07:18 +0700
commitb999a754ac553719d4953eb866c0d8e9b2633c33 (patch)
tree582e48d7553ae38e9d67a5abf9e96d8e800489fb /crypto/src
parentReduce the number of test cases (diff)
downloadBouncyCastle.NET-ed25519-b999a754ac553719d4953eb866c0d8e9b2633c33.tar.xz
Port a few more GCM/GMac updates
Diffstat (limited to 'crypto/src')
-rw-r--r--crypto/src/crypto/macs/GMac.cs179
-rw-r--r--crypto/src/crypto/modes/GCMBlockCipher.cs15
2 files changed, 100 insertions, 94 deletions
diff --git a/crypto/src/crypto/macs/GMac.cs b/crypto/src/crypto/macs/GMac.cs

index eb340ddbc..f2c3990c6 100644 --- a/crypto/src/crypto/macs/GMac.cs +++ b/crypto/src/crypto/macs/GMac.cs
@@ -8,104 +8,105 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Macs { - /// <summary> - /// The GMAC specialisation of Galois/Counter mode (GCM) detailed in NIST Special Publication - /// 800-38D. - /// </summary> - /// <remarks> - /// GMac is an invocation of the GCM mode where no data is encrypted (i.e. all input data to the Mac - /// is processed as additional authenticated data with the underlying GCM block cipher). - /// </remarks> - public class GMac - : IMac - { - private readonly GcmBlockCipher cipher; - private readonly int macSizeBits; + /// <summary> + /// The GMAC specialisation of Galois/Counter mode (GCM) detailed in NIST Special Publication + /// 800-38D. + /// </summary> + /// <remarks> + /// GMac is an invocation of the GCM mode where no data is encrypted (i.e. all input data to the Mac + /// is processed as additional authenticated data with the underlying GCM block cipher). + /// </remarks> + public class GMac + : IMac + { + private readonly GcmBlockCipher cipher; + private readonly int macSizeBits; - /// <summary> - /// Creates a GMAC based on the operation of a block cipher in GCM mode. - /// </summary> - /// <remarks> - /// This will produce an authentication code the length of the block size of the cipher. - /// </remarks> - /// <param name="cipher">the cipher to be used in GCM mode to generate the MAC.</param> - public GMac(GcmBlockCipher cipher) - : this(cipher, 128) - { - } + /// <summary> + /// Creates a GMAC based on the operation of a block cipher in GCM mode. + /// </summary> + /// <remarks> + /// This will produce an authentication code the length of the block size of the cipher. + /// </remarks> + /// <param name="cipher">the cipher to be used in GCM mode to generate the MAC.</param> + public GMac(GcmBlockCipher cipher) + : this(cipher, 128) + { + } - /// <summary> - /// Creates a GMAC based on the operation of a 128 bit block cipher in GCM mode. - /// </summary> - /// <remarks> - /// This will produce an authentication code the length of the block size of the cipher. - /// </remarks> - /// <param name="cipher">the cipher to be used in GCM mode to generate the MAC.</param> - /// <param name="macSizeBits">the mac size to generate, in bits. Must be a multiple of 8, between 96 and 128 (inclusive).</param> - public GMac(GcmBlockCipher cipher, int macSizeBits) - { - this.cipher = cipher; - this.macSizeBits = macSizeBits; - } + /// <summary> + /// Creates a GMAC based on the operation of a 128 bit block cipher in GCM mode. + /// </summary> + /// <remarks> + /// This will produce an authentication code the length of the block size of the cipher. + /// </remarks> + /// <param name="cipher">the cipher to be used in GCM mode to generate the MAC.</param> + /// <param name="macSizeBits">the mac size to generate, in bits. Must be a multiple of 8, between 32 and 128 (inclusive). + /// Sizes less than 96 are not recommended, but are supported for specialized applications.</param> + public GMac(GcmBlockCipher cipher, int macSizeBits) + { + this.cipher = cipher; + this.macSizeBits = macSizeBits; + } - /// <summary> - /// Initialises the GMAC - requires a <see cref="Org.BouncyCastle.Crypto.Parameters.ParametersWithIV"/> - /// providing a <see cref="Org.BouncyCastle.Crypto.Parameters.KeyParameter"/> and a nonce. - /// </summary> - public void Init(ICipherParameters parameters) - { - if (parameters is ParametersWithIV) - { - ParametersWithIV param = (ParametersWithIV)parameters; + /// <summary> + /// Initialises the GMAC - requires a <see cref="Org.BouncyCastle.Crypto.Parameters.ParametersWithIV"/> + /// providing a <see cref="Org.BouncyCastle.Crypto.Parameters.KeyParameter"/> and a nonce. + /// </summary> + public void Init(ICipherParameters parameters) + { + if (parameters is ParametersWithIV) + { + ParametersWithIV param = (ParametersWithIV)parameters; - byte[] iv = param.GetIV(); - KeyParameter keyParam = (KeyParameter)param.Parameters; + byte[] iv = param.GetIV(); + KeyParameter keyParam = (KeyParameter)param.Parameters; - // GCM is always operated in encrypt mode to calculate MAC - cipher.Init(true, new AeadParameters(keyParam, macSizeBits, iv)); - } - else - { - throw new ArgumentException("GMAC requires ParametersWithIV"); - } - } + // GCM is always operated in encrypt mode to calculate MAC + cipher.Init(true, new AeadParameters(keyParam, macSizeBits, iv)); + } + else + { + throw new ArgumentException("GMAC requires ParametersWithIV"); + } + } - public string AlgorithmName - { - get { return cipher.GetUnderlyingCipher().AlgorithmName + "-GMAC"; } - } + public string AlgorithmName + { + get { return cipher.GetUnderlyingCipher().AlgorithmName + "-GMAC"; } + } - public int GetMacSize() - { - return macSizeBits / 8; - } + public int GetMacSize() + { + return macSizeBits / 8; + } - public void Update(byte input) - { - cipher.ProcessAadByte(input); - } + public void Update(byte input) + { + cipher.ProcessAadByte(input); + } - public void BlockUpdate(byte[] input, int inOff, int len) - { - cipher.ProcessAadBytes(input, inOff, len); - } + public void BlockUpdate(byte[] input, int inOff, int len) + { + cipher.ProcessAadBytes(input, inOff, len); + } - public int DoFinal(byte[] output, int outOff) - { - try - { - return cipher.DoFinal(output, outOff); - } - catch (InvalidCipherTextException e) - { - // Impossible in encrypt mode - throw new InvalidOperationException(e.ToString()); - } - } + public int DoFinal(byte[] output, int outOff) + { + try + { + return cipher.DoFinal(output, outOff); + } + catch (InvalidCipherTextException e) + { + // Impossible in encrypt mode + throw new InvalidOperationException(e.ToString()); + } + } - public void Reset() - { - cipher.Reset(); - } - } + public void Reset() + { + cipher.Reset(); + } + } } diff --git a/crypto/src/crypto/modes/GCMBlockCipher.cs b/crypto/src/crypto/modes/GCMBlockCipher.cs
index 91858f6f5..2e2ac2eca 100644 --- a/crypto/src/crypto/modes/GCMBlockCipher.cs +++ b/crypto/src/crypto/modes/GCMBlockCipher.cs
@@ -79,6 +79,10 @@ namespace Org.BouncyCastle.Crypto.Modes return BlockSize; } + /// <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) @@ -96,7 +100,7 @@ namespace Org.BouncyCastle.Crypto.Modes initialAssociatedText = param.GetAssociatedText(); int macSizeBits = param.MacSize; - if (macSizeBits < 96 || macSizeBits > 128 || macSizeBits % 8 != 0) + if (macSizeBits < 32 || macSizeBits > 128 || macSizeBits % 8 != 0) { throw new ArgumentException("Invalid value for MAC size: " + macSizeBits); } @@ -126,9 +130,7 @@ namespace Org.BouncyCastle.Crypto.Modes 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?) -// this.tagLength = 16; + // 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. @@ -143,6 +145,10 @@ namespace Org.BouncyCastle.Crypto.Modes 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]; @@ -381,7 +387,6 @@ namespace Org.BouncyCastle.Crypto.Modes 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);