init commit
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Tls;
|
||||
|
||||
public class TlsStreamCipher : TlsCipher
|
||||
{
|
||||
protected readonly TlsContext context;
|
||||
|
||||
protected readonly IStreamCipher encryptCipher;
|
||||
|
||||
protected readonly IStreamCipher decryptCipher;
|
||||
|
||||
protected readonly TlsMac writeMac;
|
||||
|
||||
protected readonly TlsMac readMac;
|
||||
|
||||
protected readonly bool usesNonce;
|
||||
|
||||
public TlsStreamCipher(TlsContext context, IStreamCipher clientWriteCipher, IStreamCipher serverWriteCipher, IDigest clientWriteDigest, IDigest serverWriteDigest, int cipherKeySize, bool usesNonce)
|
||||
{
|
||||
bool isServer = context.IsServer;
|
||||
this.context = context;
|
||||
this.usesNonce = usesNonce;
|
||||
encryptCipher = clientWriteCipher;
|
||||
decryptCipher = serverWriteCipher;
|
||||
int num = 2 * cipherKeySize + clientWriteDigest.GetDigestSize() + serverWriteDigest.GetDigestSize();
|
||||
byte[] key = TlsUtilities.CalculateKeyBlock(context, num);
|
||||
int num2 = 0;
|
||||
TlsMac tlsMac = new TlsMac(context, clientWriteDigest, key, num2, clientWriteDigest.GetDigestSize());
|
||||
num2 += clientWriteDigest.GetDigestSize();
|
||||
TlsMac tlsMac2 = new TlsMac(context, serverWriteDigest, key, num2, serverWriteDigest.GetDigestSize());
|
||||
num2 += serverWriteDigest.GetDigestSize();
|
||||
KeyParameter keyParameter = new KeyParameter(key, num2, cipherKeySize);
|
||||
num2 += cipherKeySize;
|
||||
KeyParameter keyParameter2 = new KeyParameter(key, num2, cipherKeySize);
|
||||
num2 += cipherKeySize;
|
||||
if (num2 != num)
|
||||
{
|
||||
throw new TlsFatalAlert(80);
|
||||
}
|
||||
ICipherParameters parameters;
|
||||
ICipherParameters parameters2;
|
||||
if (isServer)
|
||||
{
|
||||
writeMac = tlsMac2;
|
||||
readMac = tlsMac;
|
||||
encryptCipher = serverWriteCipher;
|
||||
decryptCipher = clientWriteCipher;
|
||||
parameters = keyParameter2;
|
||||
parameters2 = keyParameter;
|
||||
}
|
||||
else
|
||||
{
|
||||
writeMac = tlsMac;
|
||||
readMac = tlsMac2;
|
||||
encryptCipher = clientWriteCipher;
|
||||
decryptCipher = serverWriteCipher;
|
||||
parameters = keyParameter;
|
||||
parameters2 = keyParameter2;
|
||||
}
|
||||
if (usesNonce)
|
||||
{
|
||||
byte[] iv = new byte[8];
|
||||
parameters = new ParametersWithIV(parameters, iv);
|
||||
parameters2 = new ParametersWithIV(parameters2, iv);
|
||||
}
|
||||
encryptCipher.Init(forEncryption: true, parameters);
|
||||
decryptCipher.Init(forEncryption: false, parameters2);
|
||||
}
|
||||
|
||||
public virtual int GetPlaintextLimit(int ciphertextLimit)
|
||||
{
|
||||
return ciphertextLimit - writeMac.Size;
|
||||
}
|
||||
|
||||
public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len)
|
||||
{
|
||||
if (usesNonce)
|
||||
{
|
||||
UpdateIV(encryptCipher, forEncryption: true, seqNo);
|
||||
}
|
||||
byte[] array = new byte[len + writeMac.Size];
|
||||
encryptCipher.ProcessBytes(plaintext, offset, len, array, 0);
|
||||
byte[] array2 = writeMac.CalculateMac(seqNo, type, plaintext, offset, len);
|
||||
encryptCipher.ProcessBytes(array2, 0, array2.Length, array, len);
|
||||
return array;
|
||||
}
|
||||
|
||||
public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len)
|
||||
{
|
||||
if (usesNonce)
|
||||
{
|
||||
UpdateIV(decryptCipher, forEncryption: false, seqNo);
|
||||
}
|
||||
int size = readMac.Size;
|
||||
if (len < size)
|
||||
{
|
||||
throw new TlsFatalAlert(50);
|
||||
}
|
||||
int num = len - size;
|
||||
byte[] array = new byte[len];
|
||||
decryptCipher.ProcessBytes(ciphertext, offset, len, array, 0);
|
||||
CheckMac(seqNo, type, array, num, len, array, 0, num);
|
||||
return Arrays.CopyOfRange(array, 0, num);
|
||||
}
|
||||
|
||||
protected virtual void CheckMac(long seqNo, byte type, byte[] recBuf, int recStart, int recEnd, byte[] calcBuf, int calcOff, int calcLen)
|
||||
{
|
||||
byte[] a = Arrays.CopyOfRange(recBuf, recStart, recEnd);
|
||||
byte[] b = readMac.CalculateMac(seqNo, type, calcBuf, calcOff, calcLen);
|
||||
if (!Arrays.ConstantTimeAreEqual(a, b))
|
||||
{
|
||||
throw new TlsFatalAlert(20);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void UpdateIV(IStreamCipher cipher, bool forEncryption, long seqNo)
|
||||
{
|
||||
byte[] array = new byte[8];
|
||||
TlsUtilities.WriteUint64(seqNo, array, 0);
|
||||
cipher.Init(forEncryption, new ParametersWithIV(null, array));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user