// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/quic/crypto/null_decrypter.h"

#include <stdint.h>

#include "net/quic/quic_utils.h"
#include "net/quic/quic_data_reader.h"

using base::StringPiece;
using std::string;

namespace net {

NullDecrypter::NullDecrypter() {}

bool NullDecrypter::SetKey(StringPiece key) { return key.empty(); }

bool NullDecrypter::SetNoncePrefix(StringPiece nonce_prefix) {
  return nonce_prefix.empty();
}

bool NullDecrypter::DecryptPacket(QuicPacketSequenceNumber /*seq_number*/,
                                  const StringPiece& associated_data,
                                  const StringPiece& ciphertext,
                                  char* output,
                                  size_t* output_length,
                                  size_t max_output_length) {
  QuicDataReader reader(ciphertext.data(), ciphertext.length());
  uint128 hash;

  if (!ReadHash(&reader, &hash)) {
    return false;
  }

  StringPiece plaintext = reader.ReadRemainingPayload();
  if (plaintext.length() > max_output_length) {
    LOG(DFATAL) << "Output buffer must be larger than the plaintext.";
    return false;
  }
  if (hash != ComputeHash(associated_data, plaintext)) {
    return false;
  }
  // Copy the plaintext to output.
  memcpy(output, plaintext.data(), plaintext.length());
  *output_length = plaintext.length();
  return true;
}

StringPiece NullDecrypter::GetKey() const { return StringPiece(); }

StringPiece NullDecrypter::GetNoncePrefix() const { return StringPiece(); }

bool NullDecrypter::ReadHash(QuicDataReader* reader, uint128* hash) {
  uint64 lo;
  uint32 hi;
  if (!reader->ReadUInt64(&lo) ||
      !reader->ReadUInt32(&hi)) {
    return false;
  }
  *hash = hi;
  *hash <<= 64;
  *hash += lo;
  return true;
}

uint128 NullDecrypter::ComputeHash(const StringPiece& data1,
                                   const StringPiece& data2) const {
  uint128 correct_hash = QuicUtils::FNV1a_128_Hash_Two(
      data1.data(), data1.length(), data2.data(), data2.length());
  uint128 mask(UINT64_C(0x0), UINT64_C(0xffffffff));
  mask <<= 96;
  correct_hash &= ~mask;
  return correct_hash;
}

}  // namespace net
