// Copyright (c) 2022 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 "quic/load_balancer/load_balancer_config.h"

#include "quic/platform/api/quic_expect_bug.h"
#include "quic/platform/api/quic_test.h"
#include "quic/test_tools/quic_test_utils.h"

namespace quic {

namespace test {

namespace {

inline constexpr char raw_key[] = {
    0xfd, 0xf7, 0x26, 0xa9, 0x89, 0x3e, 0xc0, 0x5c,
    0x06, 0x32, 0xd3, 0x95, 0x66, 0x80, 0xba, 0xf0,
};

class LoadBalancerConfigTest : public QuicTest {};

TEST_F(LoadBalancerConfigTest, InvalidParams) {
  // Bogus config_id.
  EXPECT_QUIC_BUG(
      EXPECT_FALSE(LoadBalancerConfig::CreateUnencrypted(3, 4, 10).has_value()),
      "Invalid LoadBalancerConfig Config ID 3 Server ID Length 4 "
      "Nonce Length 10");
  // Bad Server ID lengths.
  EXPECT_QUIC_BUG(EXPECT_FALSE(LoadBalancerConfig::Create(
                                   2, 0, 10, absl::string_view(raw_key, 16))
                                   .has_value()),
                  "Invalid LoadBalancerConfig Config ID 2 Server ID Length 0 "
                  "Nonce Length 10");
  EXPECT_QUIC_BUG(
      EXPECT_FALSE(LoadBalancerConfig::CreateUnencrypted(2, 16, 4).has_value()),
      "Invalid LoadBalancerConfig Config ID 2 Server ID Length 16 "
      "Nonce Length 4");
  // Bad Nonce lengths.
  EXPECT_QUIC_BUG(
      EXPECT_FALSE(LoadBalancerConfig::CreateUnencrypted(2, 4, 2).has_value()),
      "Invalid LoadBalancerConfig Config ID 2 Server ID Length 4 "
      "Nonce Length 2");
  EXPECT_QUIC_BUG(
      EXPECT_FALSE(LoadBalancerConfig::CreateUnencrypted(2, 1, 17).has_value()),
      "Invalid LoadBalancerConfig Config ID 2 Server ID Length 1 "
      "Nonce Length 17");
  // Bad key lengths.
  EXPECT_QUIC_BUG(
      EXPECT_FALSE(LoadBalancerConfig::Create(2, 3, 4, "").has_value()),
      "Invalid LoadBalancerConfig Key Length: 0");
  EXPECT_QUIC_BUG(EXPECT_FALSE(LoadBalancerConfig::Create(
                                   2, 3, 4, absl::string_view(raw_key, 10))
                                   .has_value()),
                  "Invalid LoadBalancerConfig Key Length: 10");
  EXPECT_QUIC_BUG(EXPECT_FALSE(LoadBalancerConfig::Create(
                                   0, 3, 4, absl::string_view(raw_key, 17))
                                   .has_value()),
                  "Invalid LoadBalancerConfig Key Length: 17");
}

TEST_F(LoadBalancerConfigTest, ValidParams) {
  // Test valid configurations and accessors
  auto config = LoadBalancerConfig::CreateUnencrypted(0, 3, 4);
  EXPECT_TRUE(config.has_value());
  EXPECT_EQ(config->config_id(), 0);
  EXPECT_EQ(config->server_id_len(), 3);
  EXPECT_EQ(config->nonce_len(), 4);
  EXPECT_EQ(config->total_len(), 7);
  EXPECT_FALSE(config->IsEncrypted());
  auto config2 =
      LoadBalancerConfig::Create(2, 6, 7, absl::string_view(raw_key, 16));
  EXPECT_TRUE(config.has_value());
  EXPECT_EQ(config2->config_id(), 2);
  EXPECT_EQ(config2->server_id_len(), 6);
  EXPECT_EQ(config2->nonce_len(), 7);
  EXPECT_EQ(config2->total_len(), 13);
  EXPECT_TRUE(config2->IsEncrypted());
}

// Compare EncryptionPass() results to the example in
// draft-ietf-quic-load-balancers-12, Section 5.3.2.
TEST_F(LoadBalancerConfigTest, TestEncryptionPassExample) {
  auto config =
      LoadBalancerConfig::Create(0, 3, 4, absl::string_view(raw_key, 16));
  EXPECT_TRUE(config.has_value());
  EXPECT_TRUE(config->IsEncrypted());
  std::array<uint8_t, 7> bytes = {
      0x31, 0x44, 0x1a, 0x9c, 0x69, 0xc2, 0x75,
  };
  EXPECT_FALSE(config->EncryptionPass(nullptr, 0));
  EXPECT_TRUE(config->EncryptionPass(bytes.data(), 1));
  EXPECT_TRUE((bytes == std::array<uint8_t, 7>(
                            {0x31, 0x44, 0x1a, 0x9d, 0xbc, 0x04, 0x26})));
  EXPECT_TRUE(config->EncryptionPass(bytes.data(), 2));
  EXPECT_TRUE((bytes == std::array<uint8_t, 7>(
                            {0x4f, 0xdd, 0x0c, 0x9d, 0xbc, 0x04, 0x26})));
  EXPECT_TRUE(config->EncryptionPass(bytes.data(), 3));
  EXPECT_TRUE((bytes == std::array<uint8_t, 7>(
                            {0x4f, 0xdd, 0x0c, 0x9b, 0xba, 0x1e, 0xe0})));
  EXPECT_TRUE(config->EncryptionPass(bytes.data(), 4));
  EXPECT_TRUE((bytes == std::array<uint8_t, 7>(
                            {0xe2, 0x3c, 0xb4, 0x2b, 0xba, 0x1e, 0xe0})));
}

TEST_F(LoadBalancerConfigTest, EncryptionPassPlaintext) {
  auto config = LoadBalancerConfig::CreateUnencrypted(0, 3, 4);
  std::array<uint8_t, 7> bytes = {
      0x31, 0x44, 0x1a, 0x9c, 0x69, 0xc2, 0x75,
  };
  EXPECT_FALSE(config->EncryptionPass(bytes.data(), 1));
}

TEST_F(LoadBalancerConfigTest, InvalidBlockEncryption) {
  uint8_t pt[kLoadBalancerBlockSize], ct[kLoadBalancerBlockSize];
  auto pt_config = LoadBalancerConfig::CreateUnencrypted(0, 8, 8);
  EXPECT_FALSE(pt_config->BlockEncrypt(pt, ct));
  EXPECT_FALSE(pt_config->BlockDecrypt(ct, pt));
  EXPECT_FALSE(pt_config->EncryptionPass(pt, 0));
  auto small_cid_config =
      LoadBalancerConfig::Create(0, 3, 4, absl::string_view(raw_key, 16));
  EXPECT_TRUE(small_cid_config->BlockEncrypt(pt, ct));
  EXPECT_FALSE(small_cid_config->BlockDecrypt(ct, pt));
  auto block_config =
      LoadBalancerConfig::Create(0, 8, 8, absl::string_view(raw_key, 16));
  EXPECT_TRUE(block_config->BlockEncrypt(pt, ct));
  EXPECT_TRUE(block_config->BlockDecrypt(ct, pt));
}

// Block decrypt test from the Test Vector in
// draft-ietf-quic-load-balancers-12, Appendix B.
TEST_F(LoadBalancerConfigTest, BlockEncryptionExample) {
  const uint8_t ptext[] = {0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f, 0x5f,
                           0xee, 0x08, 0x0d, 0xbf, 0x48, 0xc0, 0xd1, 0xe5};
  const uint8_t ctext[] = {0x4d, 0xd2, 0xd0, 0x5a, 0x7b, 0x0d, 0xe9, 0xb2,
                           0xb9, 0x90, 0x7a, 0xfb, 0x5e, 0xcf, 0x8c, 0xc3};
  const char key[] = {0x8f, 0x95, 0xf0, 0x92, 0x45, 0x76, 0x5f, 0x80,
                      0x25, 0x69, 0x34, 0xe5, 0x0c, 0x66, 0x20, 0x7f};
  uint8_t result[sizeof(ptext)];
  auto config = LoadBalancerConfig::Create(0, 8, 8, absl::string_view(key, 16));
  EXPECT_TRUE(config->BlockEncrypt(ptext, result));
  EXPECT_EQ(memcmp(result, ctext, sizeof(ctext)), 0);
  EXPECT_TRUE(config->BlockDecrypt(ctext, result));
  EXPECT_EQ(memcmp(result, ptext, sizeof(ptext)), 0);
}

}  // namespace

}  // namespace test

}  // namespace quic
