init commit
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class Rfc3394WrapEngine : IWrapper
|
||||
{
|
||||
private readonly IBlockCipher engine;
|
||||
|
||||
private KeyParameter param;
|
||||
|
||||
private bool forWrapping;
|
||||
|
||||
private byte[] iv = new byte[8] { 166, 166, 166, 166, 166, 166, 166, 166 };
|
||||
|
||||
public virtual string AlgorithmName => engine.AlgorithmName;
|
||||
|
||||
public Rfc3394WrapEngine(IBlockCipher engine)
|
||||
{
|
||||
this.engine = engine;
|
||||
}
|
||||
|
||||
public virtual void Init(bool forWrapping, ICipherParameters parameters)
|
||||
{
|
||||
this.forWrapping = forWrapping;
|
||||
if (parameters is ParametersWithRandom)
|
||||
{
|
||||
parameters = ((ParametersWithRandom)parameters).Parameters;
|
||||
}
|
||||
if (parameters is KeyParameter)
|
||||
{
|
||||
param = (KeyParameter)parameters;
|
||||
}
|
||||
else if (parameters is ParametersWithIV)
|
||||
{
|
||||
ParametersWithIV parametersWithIV = (ParametersWithIV)parameters;
|
||||
byte[] iV = parametersWithIV.GetIV();
|
||||
if (iV.Length != 8)
|
||||
{
|
||||
throw new ArgumentException("IV length not equal to 8", "parameters");
|
||||
}
|
||||
iv = iV;
|
||||
param = (KeyParameter)parametersWithIV.Parameters;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual byte[] Wrap(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
if (!forWrapping)
|
||||
{
|
||||
throw new InvalidOperationException("not set for wrapping");
|
||||
}
|
||||
int num = inLen / 8;
|
||||
if (num * 8 != inLen)
|
||||
{
|
||||
throw new DataLengthException("wrap data must be a multiple of 8 bytes");
|
||||
}
|
||||
byte[] array = new byte[inLen + iv.Length];
|
||||
byte[] array2 = new byte[8 + iv.Length];
|
||||
Array.Copy(iv, 0, array, 0, iv.Length);
|
||||
Array.Copy(input, inOff, array, iv.Length, inLen);
|
||||
engine.Init(forEncryption: true, param);
|
||||
for (int i = 0; i != 6; i++)
|
||||
{
|
||||
for (int j = 1; j <= num; j++)
|
||||
{
|
||||
Array.Copy(array, 0, array2, 0, iv.Length);
|
||||
Array.Copy(array, 8 * j, array2, iv.Length, 8);
|
||||
engine.ProcessBlock(array2, 0, array2, 0);
|
||||
int num2 = num * i + j;
|
||||
int num3 = 1;
|
||||
while (num2 != 0)
|
||||
{
|
||||
byte b = (byte)num2;
|
||||
byte[] array4;
|
||||
byte[] array3 = (array4 = array2);
|
||||
int num4 = iv.Length - num3;
|
||||
nint num5 = num4;
|
||||
array3[num4] = (byte)(array4[num5] ^ b);
|
||||
num2 >>>= 8;
|
||||
num3++;
|
||||
}
|
||||
Array.Copy(array2, 0, array, 0, 8);
|
||||
Array.Copy(array2, 8, array, 8 * j, 8);
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public virtual byte[] Unwrap(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
if (forWrapping)
|
||||
{
|
||||
throw new InvalidOperationException("not set for unwrapping");
|
||||
}
|
||||
int num = inLen / 8;
|
||||
if (num * 8 != inLen)
|
||||
{
|
||||
throw new InvalidCipherTextException("unwrap data must be a multiple of 8 bytes");
|
||||
}
|
||||
byte[] array = new byte[inLen - iv.Length];
|
||||
byte[] array2 = new byte[iv.Length];
|
||||
byte[] array3 = new byte[8 + iv.Length];
|
||||
Array.Copy(input, inOff, array2, 0, iv.Length);
|
||||
Array.Copy(input, inOff + iv.Length, array, 0, inLen - iv.Length);
|
||||
engine.Init(forEncryption: false, param);
|
||||
num--;
|
||||
for (int num2 = 5; num2 >= 0; num2--)
|
||||
{
|
||||
for (int num3 = num; num3 >= 1; num3--)
|
||||
{
|
||||
Array.Copy(array2, 0, array3, 0, iv.Length);
|
||||
Array.Copy(array, 8 * (num3 - 1), array3, iv.Length, 8);
|
||||
int num4 = num * num2 + num3;
|
||||
int num5 = 1;
|
||||
while (num4 != 0)
|
||||
{
|
||||
byte b = (byte)num4;
|
||||
byte[] array5;
|
||||
byte[] array4 = (array5 = array3);
|
||||
int num6 = iv.Length - num5;
|
||||
nint num7 = num6;
|
||||
array4[num6] = (byte)(array5[num7] ^ b);
|
||||
num4 >>>= 8;
|
||||
num5++;
|
||||
}
|
||||
engine.ProcessBlock(array3, 0, array3, 0);
|
||||
Array.Copy(array3, 0, array2, 0, 8);
|
||||
Array.Copy(array3, 8, array, 8 * (num3 - 1), 8);
|
||||
}
|
||||
}
|
||||
if (!Arrays.ConstantTimeAreEqual(array2, iv))
|
||||
{
|
||||
throw new InvalidCipherTextException("checksum failed");
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user