GMac
The GMAC specialisation of Galois/Counter mode (GCM) detailed in NIST Special Publication
800-38D.
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
using System;
namespace Org.BouncyCastle.Crypto.Macs
{
public class GMac : IMac
{
private readonly GcmBlockCipher cipher;
private readonly int macSizeBits;
public string AlgorithmName => cipher.UnderlyingCipher.AlgorithmName + "-GMAC";
public GMac(GcmBlockCipher cipher)
: this(cipher, 128)
{
}
public GMac(GcmBlockCipher cipher, int macSizeBits)
{
this.cipher = cipher;
this.macSizeBits = macSizeBits;
}
public void Init(ICipherParameters parameters)
{
ParametersWithIV parametersWithIV = parameters as ParametersWithIV;
if (parametersWithIV != null) {
byte[] iV = parametersWithIV.GetIV();
KeyParameter key = (KeyParameter)parametersWithIV.Parameters;
cipher.Init(true, new AeadParameters(key, macSizeBits, iV));
return;
}
throw new ArgumentException("GMAC requires ParametersWithIV");
}
public int GetMacSize()
{
return macSizeBits / 8;
}
public void Update(byte input)
{
cipher.ProcessAadByte(input);
}
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 ex) {
throw new InvalidOperationException(ex.ToString());
}
}
public void Reset()
{
cipher.Reset();
}
}
}