TlsNullCipher
The NULL cipher.
using Org.BouncyCastle.Utilities;
using System;
namespace Org.BouncyCastle.Tls.Crypto.Impl
{
public class TlsNullCipher : TlsCipher, TlsCipherExt
{
protected readonly TlsCryptoParameters m_cryptoParams;
protected readonly TlsSuiteHmac m_readMac;
protected readonly TlsSuiteHmac m_writeMac;
protected readonly byte[] m_decryptConnectionID;
protected readonly byte[] m_encryptConnectionID;
protected readonly bool m_decryptUseInnerPlaintext;
protected readonly bool m_encryptUseInnerPlaintext;
public virtual bool UsesOpaqueRecordType => false;
public unsafe TlsNullCipher(TlsCryptoParameters cryptoParams, TlsHmac clientMac, TlsHmac serverMac)
{
SecurityParameters securityParameters = cryptoParams.SecurityParameters;
if (TlsImplUtilities.IsTlsV13(securityParameters.NegotiatedVersion))
throw new TlsFatalAlert(80);
m_decryptConnectionID = securityParameters.ConnectionIDPeer;
m_encryptConnectionID = securityParameters.ConnectionIDLocal;
m_decryptUseInnerPlaintext = !Arrays.IsNullOrEmpty(m_decryptConnectionID);
m_encryptUseInnerPlaintext = !Arrays.IsNullOrEmpty(m_encryptConnectionID);
m_cryptoParams = cryptoParams;
int num = clientMac.MacLength + serverMac.MacLength;
Span<byte> span;
int num2;
if (num <= 512) {
num2 = num;
span = new Span<byte>(stackalloc byte[(int)(uint)num2], num2);
} else
span = new byte[num];
Span<byte> keyBlock = span;
TlsImplUtilities.CalculateKeyBlock(cryptoParams, keyBlock);
clientMac.SetKey(keyBlock.Slice(0, clientMac.MacLength));
num2 = clientMac.MacLength;
keyBlock = keyBlock.Slice(num2, keyBlock.Length - num2);
serverMac.SetKey(keyBlock.Slice(0, serverMac.MacLength));
num2 = serverMac.MacLength;
keyBlock = keyBlock.Slice(num2, keyBlock.Length - num2);
if (!keyBlock.IsEmpty)
throw new TlsFatalAlert(80);
if (cryptoParams.IsServer) {
m_writeMac = new TlsSuiteHmac(cryptoParams, serverMac);
m_readMac = new TlsSuiteHmac(cryptoParams, clientMac);
} else {
m_writeMac = new TlsSuiteHmac(cryptoParams, clientMac);
m_readMac = new TlsSuiteHmac(cryptoParams, serverMac);
}
}
public virtual int GetCiphertextDecodeLimit(int plaintextLimit)
{
return plaintextLimit + (m_decryptUseInnerPlaintext ? 1 : 0) + m_readMac.Size;
}
public virtual int GetCiphertextEncodeLimit(int plaintextLength, int plaintextLimit)
{
plaintextLimit = System.Math.Min(plaintextLength, plaintextLimit);
return plaintextLimit + (m_encryptUseInnerPlaintext ? 1 : 0) + m_writeMac.Size;
}
public virtual int GetPlaintextLimit(int ciphertextLimit)
{
return GetPlaintextEncodeLimit(ciphertextLimit);
}
public virtual int GetPlaintextDecodeLimit(int ciphertextLimit)
{
return ciphertextLimit - m_readMac.Size - (m_decryptUseInnerPlaintext ? 1 : 0);
}
public virtual int GetPlaintextEncodeLimit(int ciphertextLimit)
{
return ciphertextLimit - m_writeMac.Size - (m_encryptUseInnerPlaintext ? 1 : 0);
}
public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, int headerAllocation, byte[] plaintext, int offset, int len)
{
return EncodePlaintext(seqNo, contentType, recordVersion, headerAllocation, plaintext.AsSpan(offset, len));
}
public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, int headerAllocation, ReadOnlySpan<byte> plaintext)
{
int size = m_writeMac.Size;
int num = plaintext.Length + (m_encryptUseInnerPlaintext ? 1 : 0);
byte[] array = new byte[headerAllocation + num + size];
plaintext.CopyTo(array.AsSpan(headerAllocation));
short num2 = contentType;
if (m_encryptUseInnerPlaintext) {
array[headerAllocation + plaintext.Length] = (byte)contentType;
num2 = 25;
}
m_writeMac.CalculateMac(seqNo, num2, m_encryptConnectionID, array.AsSpan(headerAllocation, num)).CopyTo(array.AsSpan(headerAllocation + num));
return new TlsEncodeResult(array, 0, array.Length, num2);
}
public virtual TlsDecodeResult DecodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion, byte[] ciphertext, int offset, int len)
{
int size = m_readMac.Size;
int num = len - size;
if (num < (m_decryptUseInnerPlaintext ? 1 : 0))
throw new TlsFatalAlert(50);
byte[] a = m_readMac.CalculateMac(seqNo, recordType, m_decryptConnectionID, ciphertext, offset, num);
if (!TlsUtilities.ConstantTimeAreEqual(size, a, 0, ciphertext, offset + num))
throw new TlsFatalAlert(20);
short contentType = recordType;
int num2 = num;
if (m_decryptUseInnerPlaintext) {
byte b;
do {
if (--num2 < 0)
throw new TlsFatalAlert(10);
b = ciphertext[offset + num2];
} while (b == 0);
contentType = (short)(b & 255);
}
return new TlsDecodeResult(ciphertext, offset, num2, contentType);
}
public virtual void RekeyDecoder()
{
throw new TlsFatalAlert(80);
}
public virtual void RekeyEncoder()
{
throw new TlsFatalAlert(80);
}
}
}