public void TestRecordEncryptSequenceChange() { var prov = new BulkCipherProvider(); var bKey = (AeadBulkCipherInstance)prov.GetCipherKey(BulkCipherType.AES_128_GCM); bKey.SetKey(key); bKey.SetIV(iv); bKey.WithPadding(paddingLength); for (int i = 0; i < sequenceChange; i++) { bKey.IncrementSequence(); } using (var factory = new PipelineFactory()) { var pipe = factory.Create(); var pipeWriter = factory.Create(); var state = new ServerStateTls13Draft18(_listener); //state.WriteKey = bKey; var buff = pipe.Alloc(); var buffWrite = pipeWriter.Alloc(); buffWrite.Write(plainText); var reader = buffWrite.AsReadableBuffer(); RecordProcessor.WriteRecord(ref buff, (RecordType)plainText[0], reader.Slice(5), state); var result = buff.AsReadableBuffer().ToArray(); Assert.Equal <byte>(message2, result); buff.FlushAsync().Wait(); } }
internal unsafe static void ReadClientFinished(ReadableBuffer messageBuffer, ServerStateTls13Draft18 state) { messageBuffer = messageBuffer.Slice(4); var hashSize = state.HandshakeHash.HashSize; //We could let the equals function worry about this //however to avoid allocations we will copy a fragmented //client hash into the stack as it is small //however an attacker could send a large messge //and cause a stack overflow if (messageBuffer.Length != hashSize) { Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.decode_error, "Client finished is the wrong size (not equal to hash size)"); } //We have the client hash so we need to grab the client base key //and the hash up until now and make sure that the data is good var hash = stackalloc byte[hashSize]; state.HandshakeHash.InterimHash(hash, hashSize); var key = state.KeySchedule.GenerateClientFinishedKey(); fixed(byte *kPtr = key) { state.CryptoProvider.HashProvider.HmacData(state.CipherSuite.HashType, kPtr, key.Length, hash, hashSize, hash, hashSize); } Span <byte> clientHash; GCHandle handle = default(GCHandle); if (messageBuffer.IsSingleSpan) { var ptr = messageBuffer.First.GetPointer(out handle); clientHash = new Span <byte>(ptr, hashSize); } else { var bptr = stackalloc byte[hashSize]; clientHash = new Span <byte>(bptr, hashSize); messageBuffer.CopyTo(clientHash); } try { if (!Internal.CompareFunctions.ConstantTimeEquals(clientHash, new Span <byte>(hash, hashSize))) { Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.bad_record_mac, "The mac of the client finished did not match the expected"); } } finally { if (handle.IsAllocated) { handle.Free(); } } }
public void TestRecordDecrypt() { var prov = new BulkCipherProvider(); var bKey = prov.GetCipherKey(BulkCipherType.AES_128_GCM); bKey.SetKey(key); bKey.SetIV(iv); using (var factory = new PipelineFactory()) { var pipe = factory.Create(); var buffer = pipe.Alloc(); buffer.Write(message1); buffer.FlushAsync().Wait(); var reader = pipe.ReadAsync(); var result = reader.GetResult().Buffer; var state = new ServerStateTls13Draft18(_listener); //state.ReadKey = bKey; var header = RecordProcessor.ReadRecord(ref result, state); Assert.Equal(RecordType.Alert, header); Assert.Equal <byte>(plainText.Skip(5), result.ToArray()); } }
public void TestRecordEncryptNoPadding() { var prov = new BulkCipherProvider(); var bKey = prov.GetCipherKey(BulkCipherType.AES_128_GCM); bKey.SetKey(key); bKey.SetIV(iv); using (var factory = new PipelineFactory()) { var pipe = factory.Create(); var pipeWriter = factory.Create(); var state = new ServerStateTls13Draft18(_listener); //state.WriteKey = bKey; var buff = pipe.Alloc(); var buffWrite = pipeWriter.Alloc(); buffWrite.Write(plainText); var reader = buffWrite.AsReadableBuffer(); RecordProcessor.WriteRecord(ref buff, (RecordType)plainText[0], reader.Slice(5), state); var result = buff.AsReadableBuffer().ToArray(); Assert.Equal <byte>(message0, result); buff.FlushAsync().Wait(); } }