培训考核三期,新版培训,网页版培训登录器
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
4.1 KiB

#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs
{
/// <summary>
/// Implementation of DSTU7564 mac mode
/// </summary>
public class Dstu7564Mac
: IMac
{
private Dstu7564Digest engine;
private int macSize;
private ulong inputLength;
byte[] paddedKey;
byte[] invertedKey;
public string AlgorithmName
{
get { return "DSTU7564Mac"; }
}
public Dstu7564Mac(int macSizeBits)
{
engine = new Dstu7564Digest(macSizeBits);
macSize = macSizeBits / 8;
}
public void Init(ICipherParameters parameters)
{
if (parameters is KeyParameter)
{
byte[] key = ((KeyParameter)parameters).GetKey();
invertedKey = new byte[key.Length];
paddedKey = PadKey(key);
for (int byteIndex = 0; byteIndex < invertedKey.Length; byteIndex++)
{
invertedKey[byteIndex] = (byte)(key[byteIndex] ^ (byte)0xFF);
}
}
else
{
throw new ArgumentException("Bad parameter passed");
}
engine.BlockUpdate(paddedKey, 0, paddedKey.Length);
}
public int GetMacSize()
{
return macSize;
}
public void BlockUpdate(byte[] input, int inOff, int len)
{
Check.DataLength(input, inOff, len, "Input buffer too short");
if (paddedKey == null)
throw new InvalidOperationException(AlgorithmName + " not initialised");
engine.BlockUpdate(input, inOff, len);
inputLength += (ulong)len;
}
public void Update(byte input)
{
engine.Update(input);
inputLength++;
}
public int DoFinal(byte[] output, int outOff)
{
Check.OutputLength(output, outOff, macSize, "Output buffer too short");
if (paddedKey == null)
throw new InvalidOperationException(AlgorithmName + " not initialised");
Pad();
engine.BlockUpdate(invertedKey, 0, invertedKey.Length);
inputLength = 0;
return engine.DoFinal(output, outOff);
}
public void Reset()
{
inputLength = 0;
engine.Reset();
if (paddedKey != null)
{
engine.BlockUpdate(paddedKey, 0, paddedKey.Length);
}
}
private void Pad()
{
int extra = engine.GetByteLength() - (int)(inputLength % (ulong)engine.GetByteLength());
if (extra < 13) // terminator byte + 96 bits of length
{
extra += engine.GetByteLength();
}
byte[] padded = new byte[extra];
padded[0] = (byte)0x80; // Defined in standard;
// Defined in standard;
Pack.UInt64_To_LE(inputLength * 8, padded, padded.Length - 12);
engine.BlockUpdate(padded, 0, padded.Length);
}
private byte[] PadKey(byte[] input)
{
int paddedLen = ((input.Length + engine.GetByteLength() - 1) / engine.GetByteLength()) * engine.GetByteLength();
int extra = engine.GetByteLength() - (int)(input.Length % engine.GetByteLength());
if (extra < 13) // terminator byte + 96 bits of length
{
paddedLen += engine.GetByteLength();
}
byte[] padded = new byte[paddedLen];
Array.Copy(input, 0, padded, 0, input.Length);
padded[input.Length] = (byte)0x80; // Defined in standard;
Pack.UInt32_To_LE((uint)(input.Length * 8), padded, padded.Length - 12); // Defined in standard;
return padded;
}
}
}
#pragma warning restore
#endif