108 lines
2.6 KiB
C#
108 lines
2.6 KiB
C#
using System;
|
|
using Org.BouncyCastle.Crypto.Digests;
|
|
using Org.BouncyCastle.Crypto.Macs;
|
|
using Org.BouncyCastle.Crypto.Parameters;
|
|
using Org.BouncyCastle.Security;
|
|
using Org.BouncyCastle.Utilities;
|
|
|
|
namespace Org.BouncyCastle.Crypto.Tls;
|
|
|
|
public class TlsMac
|
|
{
|
|
protected readonly TlsContext context;
|
|
|
|
protected readonly byte[] secret;
|
|
|
|
protected readonly IMac mac;
|
|
|
|
protected readonly int digestBlockSize;
|
|
|
|
protected readonly int digestOverhead;
|
|
|
|
protected readonly int macLength;
|
|
|
|
public virtual byte[] MacSecret => secret;
|
|
|
|
public virtual int Size => macLength;
|
|
|
|
public TlsMac(TlsContext context, IDigest digest, byte[] key, int keyOff, int keyLen)
|
|
{
|
|
this.context = context;
|
|
KeyParameter keyParameter = new KeyParameter(key, keyOff, keyLen);
|
|
secret = Arrays.Clone(keyParameter.GetKey());
|
|
if (digest is LongDigest)
|
|
{
|
|
digestBlockSize = 128;
|
|
digestOverhead = 16;
|
|
}
|
|
else
|
|
{
|
|
digestBlockSize = 64;
|
|
digestOverhead = 8;
|
|
}
|
|
if (TlsUtilities.IsSsl(context))
|
|
{
|
|
mac = new Ssl3Mac(digest);
|
|
if (digest.GetDigestSize() == 20)
|
|
{
|
|
digestOverhead = 4;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mac = new HMac(digest);
|
|
}
|
|
mac.Init(keyParameter);
|
|
macLength = mac.GetMacSize();
|
|
if (context.SecurityParameters.truncatedHMac)
|
|
{
|
|
macLength = System.Math.Min(macLength, 10);
|
|
}
|
|
}
|
|
|
|
public virtual byte[] CalculateMac(long seqNo, byte type, byte[] message, int offset, int length)
|
|
{
|
|
ProtocolVersion serverVersion = context.ServerVersion;
|
|
bool isSsl = serverVersion.IsSsl;
|
|
byte[] array = new byte[isSsl ? 11 : 13];
|
|
TlsUtilities.WriteUint64(seqNo, array, 0);
|
|
TlsUtilities.WriteUint8(type, array, 8);
|
|
if (!isSsl)
|
|
{
|
|
TlsUtilities.WriteVersion(serverVersion, array, 9);
|
|
}
|
|
TlsUtilities.WriteUint16(length, array, array.Length - 2);
|
|
mac.BlockUpdate(array, 0, array.Length);
|
|
mac.BlockUpdate(message, offset, length);
|
|
return Truncate(MacUtilities.DoFinal(mac));
|
|
}
|
|
|
|
public virtual byte[] CalculateMacConstantTime(long seqNo, byte type, byte[] message, int offset, int length, int fullLength, byte[] dummyData)
|
|
{
|
|
byte[] result = CalculateMac(seqNo, type, message, offset, length);
|
|
int num = (TlsUtilities.IsSsl(context) ? 11 : 13);
|
|
int num2 = GetDigestBlockCount(num + fullLength) - GetDigestBlockCount(num + length);
|
|
while (--num2 >= 0)
|
|
{
|
|
mac.BlockUpdate(dummyData, 0, digestBlockSize);
|
|
}
|
|
mac.Update(dummyData[0]);
|
|
mac.Reset();
|
|
return result;
|
|
}
|
|
|
|
protected virtual int GetDigestBlockCount(int inputLength)
|
|
{
|
|
return (inputLength + digestOverhead) / digestBlockSize;
|
|
}
|
|
|
|
protected virtual byte[] Truncate(byte[] bs)
|
|
{
|
|
if (bs.Length <= macLength)
|
|
{
|
|
return bs;
|
|
}
|
|
return Arrays.CopyOf(bs, macLength);
|
|
}
|
|
}
|