summary refs log tree commit diff
path: root/crypto/src/crypto/tls/TlsAeadCipher.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/crypto/tls/TlsAeadCipher.cs')
-rw-r--r--crypto/src/crypto/tls/TlsAeadCipher.cs62
1 files changed, 47 insertions, 15 deletions
diff --git a/crypto/src/crypto/tls/TlsAeadCipher.cs b/crypto/src/crypto/tls/TlsAeadCipher.cs

index 951e8663b..bff719db1 100644 --- a/crypto/src/crypto/tls/TlsAeadCipher.cs +++ b/crypto/src/crypto/tls/TlsAeadCipher.cs
@@ -10,9 +10,13 @@ namespace Org.BouncyCastle.Crypto.Tls public class TlsAeadCipher : TlsCipher { + public const int NONCE_RFC5288 = 1; + internal const int NONCE_DRAFT_ZAUNER_TLS_AES_OCB = 2; + protected readonly TlsContext context; protected readonly int macSize; - protected readonly int nonce_explicit_length; + // TODO SecurityParameters.record_iv_length + protected readonly int record_iv_length; protected readonly IAeadBlockCipher encryptCipher; protected readonly IAeadBlockCipher decryptCipher; @@ -22,16 +26,32 @@ namespace Org.BouncyCastle.Crypto.Tls /// <exception cref="IOException"></exception> public TlsAeadCipher(TlsContext context, IAeadBlockCipher clientWriteCipher, IAeadBlockCipher serverWriteCipher, int cipherKeySize, int macSize) + : this(context, clientWriteCipher, serverWriteCipher, cipherKeySize, macSize, NONCE_RFC5288) + { + } + + /// <exception cref="IOException"></exception> + internal TlsAeadCipher(TlsContext context, IAeadBlockCipher clientWriteCipher, IAeadBlockCipher serverWriteCipher, + int cipherKeySize, int macSize, int nonceMode) { if (!TlsUtilities.IsTlsV12(context)) throw new TlsFatalAlert(AlertDescription.internal_error); + switch (nonceMode) + { + case NONCE_RFC5288: + this.record_iv_length = 8; + break; + case NONCE_DRAFT_ZAUNER_TLS_AES_OCB: + this.record_iv_length = 0; + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + this.context = context; this.macSize = macSize; - // NOTE: Valid for RFC 5288/6655 ciphers but may need review for other AEAD ciphers - this.nonce_explicit_length = 8; - // TODO SecurityParameters.fixed_iv_length int fixed_iv_length = 4; @@ -73,7 +93,7 @@ namespace Org.BouncyCastle.Crypto.Tls decryptKey = server_write_key; } - byte[] dummyNonce = new byte[fixed_iv_length + nonce_explicit_length]; + byte[] dummyNonce = new byte[fixed_iv_length + 8]; this.encryptCipher.Init(true, new AeadParameters(encryptKey, 8 * macSize, dummyNonce)); this.decryptCipher.Init(false, new AeadParameters(decryptKey, 8 * macSize, dummyNonce)); @@ -82,17 +102,18 @@ namespace Org.BouncyCastle.Crypto.Tls public virtual int GetPlaintextLimit(int ciphertextLimit) { // TODO We ought to be able to ask the decryptCipher (independently of it's current state!) - return ciphertextLimit - macSize - nonce_explicit_length; + return ciphertextLimit - macSize - record_iv_length; } /// <exception cref="IOException"></exception> public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len) { - byte[] nonce = new byte[this.encryptImplicitNonce.Length + nonce_explicit_length]; + byte[] nonce = new byte[this.encryptImplicitNonce.Length + 8]; Array.Copy(encryptImplicitNonce, 0, nonce, 0, encryptImplicitNonce.Length); /* - * RFC 5288/6655 The nonce_explicit MAY be the 64-bit sequence number. + * RFC 5288/6655: The nonce_explicit MAY be the 64-bit sequence number. + * draft-zauner-tls-aes-ocb-03: uses the sequence number (not included in message). * * (May need review for other AEAD ciphers). */ @@ -102,9 +123,12 @@ namespace Org.BouncyCastle.Crypto.Tls int plaintextLength = len; int ciphertextLength = encryptCipher.GetOutputSize(plaintextLength); - byte[] output = new byte[nonce_explicit_length + ciphertextLength]; - Array.Copy(nonce, encryptImplicitNonce.Length, output, 0, nonce_explicit_length); - int outputPos = nonce_explicit_length; + byte[] output = new byte[record_iv_length + ciphertextLength]; + if (record_iv_length != 0) + { + Array.Copy(nonce, nonce.Length - record_iv_length, output, 0, record_iv_length); + } + int outputPos = record_iv_length; byte[] additionalData = GetAdditionalData(seqNo, type, plaintextLength); AeadParameters parameters = new AeadParameters(null, 8 * macSize, nonce, additionalData); @@ -135,12 +159,20 @@ namespace Org.BouncyCastle.Crypto.Tls if (GetPlaintextLimit(len) < 0) throw new TlsFatalAlert(AlertDescription.decode_error); - byte[] nonce = new byte[this.decryptImplicitNonce.Length + nonce_explicit_length]; + byte[] nonce = new byte[this.decryptImplicitNonce.Length + 8]; Array.Copy(decryptImplicitNonce, 0, nonce, 0, decryptImplicitNonce.Length); - Array.Copy(ciphertext, offset, nonce, decryptImplicitNonce.Length, nonce_explicit_length); + //Array.Copy(ciphertext, offset, nonce, decryptImplicitNonce.Length, nonce_explicit_length); + if (record_iv_length == 0) + { + TlsUtilities.WriteUint64(seqNo, nonce, decryptImplicitNonce.Length); + } + else + { + Array.Copy(ciphertext, offset, nonce, nonce.Length - record_iv_length, record_iv_length); + } - int ciphertextOffset = offset + nonce_explicit_length; - int ciphertextLength = len - nonce_explicit_length; + int ciphertextOffset = offset + record_iv_length; + int ciphertextLength = len - record_iv_length; int plaintextLength = decryptCipher.GetOutputSize(ciphertextLength); byte[] output = new byte[plaintextLength];