// Copyright 2019 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////////////

#include "tink/subtle/streaming_aead_encrypting_stream.h"

#include <sstream>
#include <vector>

#include "gtest/gtest.h"
#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "tink/output_stream.h"
#include "tink/subtle/stream_segment_encrypter.h"
#include "tink/subtle/random.h"
#include "tink/subtle/test_util.h"
#include "tink/util/ostream_output_stream.h"
#include "tink/util/status.h"
#include "tink/util/statusor.h"

namespace crypto {
namespace tink {
namespace subtle {

using crypto::tink::OutputStream;
using crypto::tink::subtle::test::DummyStreamSegmentEncrypter;
using crypto::tink::util::OstreamOutputStream;

namespace {

// References to objects used for test validation.
// The objects pointed to are not owned by this structure.
struct ValidationRefs {
  std::stringbuf* ct_buf;  // buffer that contains the resulting ciphertext
  DummyStreamSegmentEncrypter* seg_enc;  // segment encrypter
};

// A helper for creating StreamingAeadEncryptingStream together
// with references to internal objects, used for test validation.
std::unique_ptr<OutputStream> GetEncryptingStream(
    int pt_segment_size, int header_size, int ct_offset, ValidationRefs* refs) {
  // Prepare ciphertext destination stream.
  auto ct_stream = absl::make_unique<std::stringstream>();
  // A reference to the ciphertext buffer, for later validation.
  refs->ct_buf = ct_stream->rdbuf();
  std::unique_ptr<OutputStream> ct_destination(
      absl::make_unique<OstreamOutputStream>(std::move(ct_stream)));
  auto seg_enc = absl::make_unique<DummyStreamSegmentEncrypter>(
          pt_segment_size, header_size, ct_offset);
  // A reference to the segment encrypter, for later validation.
  refs->seg_enc = seg_enc.get();
  auto enc_stream = std::move(StreamingAeadEncryptingStream::New(
      std::move(seg_enc), std::move(ct_destination)).ValueOrDie());
  EXPECT_EQ(0, enc_stream->Position());
  return enc_stream;
}


class StreamingAeadEncryptingStreamTest : public ::testing::Test {
};

TEST_F(StreamingAeadEncryptingStreamTest, WritingStreams) {
  std::vector<int> pt_sizes = {0, 10, 100, 1000, 10000, 100000, 1000000};
  std::vector<int> pt_segment_sizes = {64, 100, 128, 1000, 1024};
  std::vector<int> header_sizes = {5, 10, 32};
  std::vector<int> ct_offsets = {0, 1, 5, 15};
  for (auto pt_size : pt_sizes) {
    for (auto pt_segment_size : pt_segment_sizes) {
      for (auto header_size : header_sizes) {
        for (auto ct_offset : ct_offsets) {
          SCOPED_TRACE(absl::StrCat("pt_size = ", pt_size,
                                    ", pt_segment_size = ", pt_segment_size,
                                    ", header_size = ", header_size,
                                    ", ct_offset = ", ct_offset));
          // Get an encrypting stream.
          ValidationRefs refs;
          auto enc_stream = GetEncryptingStream(pt_segment_size, header_size,
              ct_offset, &refs);

          // First buffer returned by Next();
          void* buffer;
          auto next_result = enc_stream->Next(&buffer);
          EXPECT_TRUE(next_result.ok()) << next_result.status();
          int buffer_size = next_result.ValueOrDie();
          EXPECT_EQ(pt_segment_size - (header_size + ct_offset), buffer_size);
          EXPECT_EQ(buffer_size, enc_stream->Position());

          // Backup the entire first buffer.
          enc_stream->BackUp(buffer_size);
          EXPECT_EQ(0, enc_stream->Position());

          // Write plaintext to the stream, and close the stream.
          std::string pt = Random::GetRandomBytes(pt_size);
          auto status = test::WriteToStream(enc_stream.get(), pt);
          EXPECT_TRUE(status.ok()) << status;
          EXPECT_EQ(enc_stream->Position(), pt.size());
          EXPECT_EQ(refs.seg_enc->get_generated_output_size(),
                    refs.ct_buf->str().size());
          auto exp_ciphertext = refs.seg_enc->GenerateCiphertext(pt);
          EXPECT_EQ(exp_ciphertext.size(), refs.ct_buf->str().size());
          EXPECT_EQ(exp_ciphertext, refs.ct_buf->str());

          // Try closing the stream again.
          status = enc_stream->Close();
          EXPECT_FALSE(status.ok());
          EXPECT_EQ(util::error::FAILED_PRECONDITION, status.error_code());
        }
      }
    }
  }
}

TEST_F(StreamingAeadEncryptingStreamTest, EmptyPlaintext) {
  int pt_segment_size = 512;
  int header_size = 64;

  // Get an encrypting stream.
  ValidationRefs refs;
  auto enc_stream = GetEncryptingStream(
      pt_segment_size, header_size, /* ct_offset = */ 0, &refs);

  // Close the stream.
  auto close_status = enc_stream->Close();
  EXPECT_TRUE(close_status.ok()) << close_status;
  EXPECT_EQ(refs.seg_enc->get_generated_output_size(),
            refs.ct_buf->str().size());
  // Ciphertext contains only the header and an "empty" first segment.
  EXPECT_EQ(header_size + DummyStreamSegmentEncrypter::kSegmentTagSize,
            refs.ct_buf->str().size());
  // The last segment is marked as such.
  EXPECT_EQ(DummyStreamSegmentEncrypter::kLastSegment,
            refs.ct_buf->str().back());

  // Try closing the stream again.
  close_status = enc_stream->Close();
  EXPECT_FALSE(close_status.ok());
  EXPECT_EQ(util::error::FAILED_PRECONDITION, close_status.error_code());
}

TEST_F(StreamingAeadEncryptingStreamTest, EmptyPlaintextWithBackup) {
  int pt_segment_size = 512;
  int header_size = 64;
  void* buffer;

  // Get an encrypting stream.
  ValidationRefs refs;
  auto enc_stream = GetEncryptingStream(
      pt_segment_size, header_size, /* ct_offset = */ 0, &refs);

  // Get the first segment.
  auto next_result = enc_stream->Next(&buffer);
  int buffer_size = pt_segment_size - header_size;
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(buffer_size, next_result.ValueOrDie());
  EXPECT_EQ(buffer_size, enc_stream->Position());

  // Backup the entire segment, and close the stream.
  enc_stream->BackUp(buffer_size);
  EXPECT_EQ(0, enc_stream->Position());
  auto close_status = enc_stream->Close();
  EXPECT_TRUE(close_status.ok()) << close_status;
  EXPECT_EQ(refs.seg_enc->get_generated_output_size(),
            refs.ct_buf->str().size());
  // Ciphertext contains only the header and an "empty" first segment.
  EXPECT_EQ(header_size + DummyStreamSegmentEncrypter::kSegmentTagSize,
            refs.ct_buf->str().size());
  // The last segment is marked as such.
  EXPECT_EQ(DummyStreamSegmentEncrypter::kLastSegment,
            refs.ct_buf->str().back());

  // Try closing the stream again.
  close_status = enc_stream->Close();
  EXPECT_FALSE(close_status.ok());
  EXPECT_EQ(util::error::FAILED_PRECONDITION, close_status.error_code());
}

TEST_F(StreamingAeadEncryptingStreamTest, OneSegmentPlaintext) {
  int pt_segment_size = 512;
  int header_size = 64;
  void* buffer;

  // Get an encrypting stream.
  ValidationRefs refs;
  auto enc_stream = GetEncryptingStream(
      pt_segment_size, header_size, /* ct_offset = */ 0, &refs);

  // Get the first segment, and close the stream.
  auto next_result = enc_stream->Next(&buffer);
  int buffer_size = pt_segment_size - header_size;
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(buffer_size, next_result.ValueOrDie());
  EXPECT_EQ(buffer_size, enc_stream->Position());
  auto close_status = enc_stream->Close();
  EXPECT_TRUE(close_status.ok()) << close_status;
  EXPECT_EQ(refs.seg_enc->get_generated_output_size(),
            refs.ct_buf->str().size());
  // Ciphertext contains only header and a full first segment.
  EXPECT_EQ(pt_segment_size + DummyStreamSegmentEncrypter::kSegmentTagSize,
            refs.ct_buf->str().size());
  // The last segment is marked as such.
  EXPECT_EQ(DummyStreamSegmentEncrypter::kLastSegment,
            refs.ct_buf->str().back());

  // Try closing the stream again.
  close_status = enc_stream->Close();
  EXPECT_FALSE(close_status.ok());
  EXPECT_EQ(util::error::FAILED_PRECONDITION, close_status.error_code());
}

TEST_F(StreamingAeadEncryptingStreamTest, NextAfterBackup) {
  int pt_segment_size = 512;
  int part1_size = 123;
  int part2_size = 74;
  int header_size = 64;
  void* buffer;

  // Get an encrypting stream.
  ValidationRefs refs;
  auto enc_stream = GetEncryptingStream(
      pt_segment_size, header_size, /* ct_offset = */ 0, &refs);

  // Get the first segment.
  auto next_result = enc_stream->Next(&buffer);
  int buffer_size = pt_segment_size - header_size;
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(buffer_size, next_result.ValueOrDie());
  EXPECT_EQ(buffer_size, enc_stream->Position());

  // Backup so that only part1_size bytes are written.
  enc_stream->BackUp(buffer_size - part1_size);
  EXPECT_EQ(part1_size, enc_stream->Position());

  // Get backed up space.
  void* backedup_buffer;
  next_result = enc_stream->Next(&backedup_buffer);
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(buffer_size - part1_size, next_result.ValueOrDie());
  EXPECT_EQ(reinterpret_cast<uint8_t*>(buffer) + part1_size,
            reinterpret_cast<uint8_t*>(backedup_buffer));

  // Backup so again that (part1_size + part2_size) bytes are written.
  enc_stream->BackUp(buffer_size - (part1_size + part2_size));
  EXPECT_EQ(part1_size + part2_size, enc_stream->Position());

  // Get backed up space again.
  next_result = enc_stream->Next(&backedup_buffer);
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(buffer_size - (part1_size + part2_size), next_result.ValueOrDie());
  EXPECT_EQ(reinterpret_cast<uint8_t*>(buffer) + part1_size + part2_size,
            reinterpret_cast<uint8_t*>(backedup_buffer));

  // Close the stream.
  auto close_status = enc_stream->Close();
  EXPECT_TRUE(close_status.ok()) << close_status;
}

TEST_F(StreamingAeadEncryptingStreamTest, OneSegmentPlaintextWithBackup) {
  int pt_segment_size = 512;
  int pt_size = 200;
  int header_size = 64;
  void* buffer;

  // Get an encrypting stream.
  ValidationRefs refs;
  auto enc_stream = GetEncryptingStream(
      pt_segment_size, header_size, /* ct_offset = */ 0, &refs);

  // Get the first segment.
  auto next_result = enc_stream->Next(&buffer);
  int buffer_size = pt_segment_size - header_size;
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(buffer_size, next_result.ValueOrDie());
  EXPECT_EQ(buffer_size, enc_stream->Position());

  // Backup so that only pt_size bytes are written, and close the stream.
  enc_stream->BackUp(buffer_size - pt_size);
  EXPECT_EQ(pt_size, enc_stream->Position());
  auto close_status = enc_stream->Close();
  EXPECT_TRUE(close_status.ok()) << close_status;
  EXPECT_EQ(refs.seg_enc->get_generated_output_size(),
            refs.ct_buf->str().size());
  // Ciphertext contains only the header and partial first segment.
  EXPECT_EQ(
      header_size + pt_size + DummyStreamSegmentEncrypter::kSegmentTagSize,
      refs.ct_buf->str().size());
  // The last segment is marked as such.
  EXPECT_EQ(DummyStreamSegmentEncrypter::kLastSegment,
            refs.ct_buf->str().back());

  // Try closing the stream again.
  close_status = enc_stream->Close();
  EXPECT_FALSE(close_status.ok());
  EXPECT_EQ(util::error::FAILED_PRECONDITION, close_status.error_code());
}

TEST_F(StreamingAeadEncryptingStreamTest, ManySegmentsPlaintext) {
  int pt_segment_size = 512;
  int header_size = 64;
  void* buffer;

  // Get an encrypting stream.
  ValidationRefs refs;
  auto enc_stream = GetEncryptingStream(
      pt_segment_size, header_size, /* ct_offset = */ 0, &refs);

  int seg_count = 5;
  // Get the first segment.
  auto next_result = enc_stream->Next(&buffer);
  int first_buffer_size = pt_segment_size - header_size;
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(first_buffer_size, next_result.ValueOrDie());
  EXPECT_EQ(first_buffer_size, enc_stream->Position());

  // Get remaining segments.
  for (int i = 1; i < seg_count; i++) {
    next_result = enc_stream->Next(&buffer);
    EXPECT_TRUE(next_result.ok()) << next_result.status();
    EXPECT_EQ(pt_segment_size, next_result.ValueOrDie());
    EXPECT_EQ(first_buffer_size + i * pt_segment_size, enc_stream->Position());
  }

  // Close the stream.
  auto close_status = enc_stream->Close();
  EXPECT_TRUE(close_status.ok()) << close_status;
  EXPECT_EQ(refs.seg_enc->get_generated_output_size(),
            refs.ct_buf->str().size());
  // Ciphertext contains seg_count full segments.
  int ct_segment_size =
      pt_segment_size + DummyStreamSegmentEncrypter::kSegmentTagSize;
  EXPECT_EQ(refs.seg_enc->get_ciphertext_segment_size(), ct_segment_size);
  EXPECT_EQ(ct_segment_size * seg_count, refs.ct_buf->str().size());
  // The last segment is marked as such.
  EXPECT_EQ(DummyStreamSegmentEncrypter::kLastSegment,
            refs.ct_buf->str().back());
  // The previous segments are marked as not-last ones.
  for (int i = 1; i < seg_count - 1; i++) {
    EXPECT_EQ(DummyStreamSegmentEncrypter::kNotLastSegment,
              refs.ct_buf->str()[(ct_segment_size * i)-1]);
  }

  // Try closing the stream again.
  close_status = enc_stream->Close();
  EXPECT_FALSE(close_status.ok());
  EXPECT_EQ(util::error::FAILED_PRECONDITION, close_status.error_code());
}

TEST_F(StreamingAeadEncryptingStreamTest, ManySegmentsPlaintextWithBackup) {
  int pt_segment_size = 512;
  int backup_size = 100;
  int header_size = 64;
  void* buffer;

  // Get an encrypting stream.
  ValidationRefs refs;
  auto enc_stream = GetEncryptingStream(
      pt_segment_size, header_size, /* ct_offset = */ 0, &refs);

  int seg_count = 5;
  // Get the first segment.
  auto next_result = enc_stream->Next(&buffer);
  int first_buffer_size = pt_segment_size - header_size;
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(first_buffer_size, next_result.ValueOrDie());
  EXPECT_EQ(first_buffer_size, enc_stream->Position());

  // Get remaining segments.
  for (int i = 1; i < seg_count; i++) {
    next_result = enc_stream->Next(&buffer);
    EXPECT_TRUE(next_result.ok()) << next_result.status();
    EXPECT_EQ(pt_segment_size, next_result.ValueOrDie());
    EXPECT_EQ(first_buffer_size + i * pt_segment_size, enc_stream->Position());
  }
  // Backup part of the last segment, and close the stream.
  enc_stream->BackUp(backup_size);
  EXPECT_EQ(first_buffer_size + (seg_count - 1) * pt_segment_size - backup_size,
            enc_stream->Position());
  auto close_status = enc_stream->Close();
  EXPECT_TRUE(close_status.ok()) << close_status;
  EXPECT_EQ(refs.seg_enc->get_generated_output_size(),
            refs.ct_buf->str().size());
  // Ciphertext contains seg_count full segments, minus the size of the backup.
  int ct_segment_size =
      pt_segment_size + DummyStreamSegmentEncrypter::kSegmentTagSize;
  EXPECT_EQ(refs.seg_enc->get_ciphertext_segment_size(), ct_segment_size);
  EXPECT_EQ(ct_segment_size * seg_count - backup_size,
            refs.ct_buf->str().size());
  // The last segment is marked as such.
  EXPECT_EQ(DummyStreamSegmentEncrypter::kLastSegment,
            refs.ct_buf->str().back());
  // The previous segments are marked as not-last ones.
  for (int i = 1; i < seg_count - 1; i++) {
    EXPECT_EQ(DummyStreamSegmentEncrypter::kNotLastSegment,
              refs.ct_buf->str()[(ct_segment_size * i)-1]);
  }

  // Try closing the stream again.
  close_status = enc_stream->Close();
  EXPECT_FALSE(close_status.ok());
  EXPECT_EQ(util::error::FAILED_PRECONDITION, close_status.error_code());
}

TEST_F(StreamingAeadEncryptingStreamTest, ManySegmentsPlaintextWithFullBackup) {
  int pt_segment_size = 512;
  int header_size = 64;
  void* buffer;

  // Get an encrypting stream.
  ValidationRefs refs;
  auto enc_stream = GetEncryptingStream(
      pt_segment_size, header_size, /* ct_offset = */ 0, &refs);

  int seg_count = 5;
  // Get the first segment.
  auto next_result = enc_stream->Next(&buffer);
  int first_buffer_size = pt_segment_size - header_size;
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(first_buffer_size, next_result.ValueOrDie());
  EXPECT_EQ(first_buffer_size, enc_stream->Position());

  // Get remaining segments.
  for (int i = 1; i < seg_count; i++) {
    next_result = enc_stream->Next(&buffer);
    EXPECT_TRUE(next_result.ok()) << next_result.status();
    EXPECT_EQ(pt_segment_size, next_result.ValueOrDie());
    EXPECT_EQ(first_buffer_size + i * pt_segment_size, enc_stream->Position());
  }
  // Backup the entire last segment, and close the stream.
  enc_stream->BackUp(pt_segment_size);
  EXPECT_EQ(first_buffer_size + (seg_count - 2) * pt_segment_size,
            enc_stream->Position());
  auto close_status = enc_stream->Close();
  EXPECT_TRUE(close_status.ok()) << close_status;
  EXPECT_EQ(refs.seg_enc->get_generated_output_size(),
            refs.ct_buf->str().size());
  // Ciphertext contains (seg_count - 1) full segments.
  int ct_segment_size =
      pt_segment_size + DummyStreamSegmentEncrypter::kSegmentTagSize;
  EXPECT_EQ(refs.seg_enc->get_ciphertext_segment_size(), ct_segment_size);
  EXPECT_EQ(ct_segment_size * (seg_count - 1), refs.ct_buf->str().size());
  // The last segment is marked as such.
  EXPECT_EQ(DummyStreamSegmentEncrypter::kLastSegment,
            refs.ct_buf->str().back());
  // The previous segments are marked as not-last ones.
  for (int i = 1; i < seg_count - 1; i++) {
    EXPECT_EQ(DummyStreamSegmentEncrypter::kNotLastSegment,
              refs.ct_buf->str()[(ct_segment_size * i)-1]);
  }

  // Try closing the stream again.
  close_status = enc_stream->Close();
  EXPECT_FALSE(close_status.ok());
  EXPECT_EQ(util::error::FAILED_PRECONDITION, close_status.error_code());
}

TEST_F(StreamingAeadEncryptingStreamTest, BackupAndPosition) {
  int pt_segment_size = 512;
  int header_size = 64;
  void* buffer;

  // Get an encrypting stream.
  ValidationRefs refs;
  auto enc_stream = GetEncryptingStream(
      pt_segment_size, header_size, /* ct_offset = */ 0, &refs);

  // The first buffer.
  auto next_result = enc_stream->Next(&buffer);
  int buffer_size = pt_segment_size - header_size;
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(buffer_size, next_result.ValueOrDie());
  EXPECT_EQ(buffer_size, enc_stream->Position());

  // BackUp several times, but in total fewer bytes than returned by Next().
  std::vector<int> backup_sizes = {0, 1, 5, 0, 10, 78, -42, 60, 120, -120};
  int total_backup_size = 0;
  for (auto backup_size : backup_sizes) {
    enc_stream->BackUp(backup_size);
    total_backup_size += std::max(0, backup_size);
    EXPECT_EQ(buffer_size - total_backup_size, enc_stream->Position());
  }
  EXPECT_LT(total_backup_size, next_result.ValueOrDie());

  // Call Next(), it should succeed (backuped bytes of 1st segment).
  next_result = enc_stream->Next(&buffer);
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(total_backup_size, next_result.ValueOrDie());
  EXPECT_EQ(buffer_size, enc_stream->Position());

  // BackUp() some bytes, again fewer than returned by Next().
  backup_sizes = {0, 72, -94, 37, 82};
  total_backup_size = 0;
  for (auto backup_size : backup_sizes) {
    enc_stream->BackUp(backup_size);
    total_backup_size += std::max(0, backup_size);
    EXPECT_EQ(buffer_size - total_backup_size, enc_stream->Position());
  }
  EXPECT_LT(total_backup_size, next_result.ValueOrDie());

  // Call Next(), it should succeed  (backuped bytes of 1st segment).
  next_result = enc_stream->Next(&buffer);
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(total_backup_size, next_result.ValueOrDie());
  EXPECT_EQ(buffer_size, enc_stream->Position());

  // Call Next() again, it should return a full segment (2nd segment).
  auto prev_position = enc_stream->Position();
  buffer_size = pt_segment_size;
  next_result = enc_stream->Next(&buffer);
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(buffer_size, next_result.ValueOrDie());
  EXPECT_EQ(prev_position + buffer_size, enc_stream->Position());

  // BackUp a few times, with total over the returned buffer_size.
  backup_sizes = {0, 72, -100, buffer_size / 2, 200, -25, buffer_size / 2, 42};
  total_backup_size = 0;
  for (auto backup_size : backup_sizes) {
    SCOPED_TRACE(absl::StrCat("backup_size = ", backup_size,
                              ", total_backup_size = ", total_backup_size));
    enc_stream->BackUp(backup_size);
    total_backup_size = std::min(buffer_size,
                                 total_backup_size + std::max(0, backup_size));
    EXPECT_EQ(prev_position + buffer_size - total_backup_size,
              enc_stream->Position());
  }
  EXPECT_EQ(total_backup_size, buffer_size);
  EXPECT_EQ(prev_position, enc_stream->Position());

  // Call Next() again, it should return a full segment (2nd segment);
  next_result = enc_stream->Next(&buffer);
  EXPECT_TRUE(next_result.ok()) << next_result.status();
  EXPECT_EQ(buffer_size, next_result.ValueOrDie());
  EXPECT_EQ(prev_position + buffer_size, enc_stream->Position());
  EXPECT_EQ(2 * pt_segment_size - header_size, enc_stream->Position());

  // Backup the entire segment, and close the stream.
  enc_stream->BackUp(buffer_size);
  EXPECT_EQ(pt_segment_size - header_size, enc_stream->Position());
  auto close_status = enc_stream->Close();
  EXPECT_TRUE(close_status.ok()) << close_status;
  EXPECT_EQ(refs.seg_enc->get_generated_output_size(),
            refs.ct_buf->str().size());
  // Ciphertext contains 1st segment (with header), and no traces
  // of the "empty" (backed-up) segment.
  EXPECT_EQ((pt_segment_size + DummyStreamSegmentEncrypter::kSegmentTagSize),
            refs.ct_buf->str().size());

  // Try closing the stream again.
  close_status = enc_stream->Close();
  EXPECT_FALSE(close_status.ok());
  EXPECT_EQ(util::error::FAILED_PRECONDITION, close_status.error_code());
}

}  // namespace
}  // namespace subtle
}  // namespace tink
}  // namespace crypto
