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.
164 lines
4.4 KiB
164 lines
4.4 KiB
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) |
|
#pragma warning disable |
|
using System; |
|
|
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters; |
|
|
|
|
|
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs |
|
{ |
|
/** |
|
* implementation of DSTU 7624 MAC |
|
*/ |
|
public class Dstu7624Mac : IMac |
|
{ |
|
private int macSize; |
|
|
|
private Dstu7624Engine engine; |
|
private int blockSize; |
|
|
|
private byte[] c, cTemp, kDelta; |
|
private byte[] buf; |
|
private int bufOff; |
|
|
|
public Dstu7624Mac(int blockSizeBits, int q) |
|
{ |
|
engine = new Dstu7624Engine(blockSizeBits); |
|
|
|
blockSize = blockSizeBits / 8; |
|
|
|
macSize = q / 8; |
|
|
|
c = new byte[blockSize]; |
|
|
|
cTemp = new byte[blockSize]; |
|
|
|
kDelta = new byte[blockSize]; |
|
buf = new byte[blockSize]; |
|
} |
|
|
|
public void Init(ICipherParameters parameters) |
|
{ |
|
if (parameters is KeyParameter) |
|
{ |
|
engine.Init(true, (KeyParameter)parameters); |
|
|
|
engine.ProcessBlock(kDelta, 0, kDelta, 0); |
|
} |
|
else |
|
{ |
|
throw new ArgumentException("invalid parameter passed to Dstu7624Mac init - " |
|
+ BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); |
|
} |
|
} |
|
|
|
public string AlgorithmName |
|
{ |
|
get { return "Dstu7624Mac"; } |
|
} |
|
|
|
public int GetMacSize() |
|
{ |
|
return macSize; |
|
} |
|
|
|
public void Update(byte input) |
|
{ |
|
if (bufOff == buf.Length) |
|
{ |
|
processBlock(buf, 0); |
|
bufOff = 0; |
|
} |
|
|
|
buf[bufOff++] = input; |
|
} |
|
|
|
public void BlockUpdate(byte[] input, int inOff, int len) |
|
{ |
|
if (len < 0) |
|
{ |
|
throw new ArgumentException( |
|
"Can't have a negative input length!"); |
|
} |
|
|
|
int blockSize = engine.GetBlockSize(); |
|
int gapLen = blockSize - bufOff; |
|
|
|
if (len > gapLen) |
|
{ |
|
Array.Copy(input, inOff, buf, bufOff, gapLen); |
|
|
|
processBlock(buf, 0); |
|
|
|
bufOff = 0; |
|
len -= gapLen; |
|
inOff += gapLen; |
|
|
|
while (len > blockSize) |
|
{ |
|
processBlock(input, inOff); |
|
|
|
len -= blockSize; |
|
inOff += blockSize; |
|
} |
|
} |
|
|
|
Array.Copy(input, inOff, buf, bufOff, len); |
|
|
|
bufOff += len; |
|
} |
|
|
|
private void processBlock(byte[] input, int inOff) |
|
{ |
|
Xor(c, 0, input, inOff, cTemp); |
|
|
|
engine.ProcessBlock(cTemp, 0, c, 0); |
|
} |
|
|
|
private void Xor(byte[] c, int cOff, byte[] input, int inOff, byte[] xorResult) |
|
{ |
|
for (int byteIndex = 0; byteIndex < blockSize; byteIndex++) |
|
{ |
|
xorResult[byteIndex] = (byte)(c[byteIndex + cOff] ^ input[byteIndex + inOff]); |
|
} |
|
} |
|
|
|
public int DoFinal(byte[] output, int outOff) |
|
{ |
|
if (bufOff % buf.Length != 0) |
|
{ |
|
throw new DataLengthException("Input must be a multiple of blocksize"); |
|
} |
|
|
|
//Last block |
|
Xor(c, 0, buf, 0, cTemp); |
|
Xor(cTemp, 0, kDelta, 0, c); |
|
engine.ProcessBlock(c, 0, c, 0); |
|
|
|
if (macSize + outOff > output.Length) |
|
{ |
|
throw new DataLengthException("Output buffer too short"); |
|
} |
|
|
|
Array.Copy(c, 0, output, outOff, macSize); |
|
|
|
return macSize; |
|
} |
|
|
|
public void Reset() |
|
{ |
|
Arrays.Fill(c, (byte)0x00); |
|
Arrays.Fill(cTemp, (byte)0x00); |
|
Arrays.Fill(kDelta, (byte)0x00); |
|
Arrays.Fill(buf, (byte)0x00); |
|
engine.Reset(); |
|
engine.ProcessBlock(kDelta, 0, kDelta, 0); |
|
bufOff = 0; |
|
} |
|
} |
|
} |
|
#pragma warning restore |
|
#endif
|
|
|