// Copyright 2018 The Chromium OS 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 <stdint.h>

#include <base/check.h>
#include <base/check_op.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/stringprintf.h>
#include <brillo/secure_blob.h>
#include <crypto/scoped_openssl_types.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>

#include "cryptohome/crypto/rsa.h"
#include "cryptohome/fuzzers/blob_mutator.h"

using brillo::Blob;
using brillo::BlobFromString;
using brillo::SecureBlob;
using crypto::ScopedRSA;

namespace {

constexpr char kStaticFilesPath[] = "/usr/libexec/fuzzers/";

constexpr int kMaxPlaintextLength = 5;
constexpr int kMaxOaepLabelLength = 5;

struct Environment {
  Environment();

  // The RSA keys loaded from the data files installed next to the fuzzer.
  static constexpr int kRsaKeyCount = 8;
  ScopedRSA rsa_keys[kRsaKeyCount];
};

struct ScopedOpensslErrorClearer {
  ~ScopedOpensslErrorClearer() { ERR_clear_error(); }
};

ScopedRSA LoadRsaPrivateKeyFromPemFile(const base::FilePath& pem_file_path) {
  std::string pem_data;
  CHECK(base::ReadFileToString(pem_file_path, &pem_data));
  crypto::ScopedBIO pem_data_bio(
      BIO_new_mem_buf(pem_data.data(), pem_data.size()));
  CHECK(pem_data_bio);
  crypto::ScopedRSA rsa(PEM_read_bio_RSAPrivateKey(
      pem_data_bio.get(), /*RSA **x=*/nullptr, /*pem_password_cb *cb=*/nullptr,
      /*void *u=*/nullptr));
  CHECK(rsa);
  return rsa;
}

Environment::Environment() {
  logging::SetMinLogLevel(logging::LOGGING_FATAL);

  int key_index = 0;
  for (int key_size : {512, 1024, 2048, 4096}) {
    for (int current_key_number : {1, 2}) {
      const base::FilePath key_file_path =
          base::FilePath(kStaticFilesPath)
              .AppendASCII(base::StringPrintf("cryptohome_fuzzer_key_rsa_%d_%d",
                                              key_size, current_key_number));
      CHECK_LT(key_index, kRsaKeyCount);
      rsa_keys[key_index] = LoadRsaPrivateKeyFromPemFile(key_file_path);
      ++key_index;
    }
  }
}

// Returns a mutated RSA-OAEP encrypted blob of the given plaintext.
Blob FuzzedRsaOaepEncrypt(const Blob& plaintext,
                          const Blob& oaep_label,
                          RSA* rsa,
                          FuzzedDataProvider* fuzzed_data_provider) {
  // Explicitly do the padding step first, in order to be able to mutate its
  // result before the actual RSA operation.
  Blob padded_blob(RSA_size(rsa));
  RSA_padding_add_PKCS1_OAEP_mgf1(
      padded_blob.data(), padded_blob.size(), plaintext.data(),
      plaintext.size(), oaep_label.data(), oaep_label.size(), nullptr, nullptr);

  Blob fuzzed_padded_blob =
      MutateBlob(padded_blob, /*min_length=*/RSA_size(rsa),
                 /*max_length=*/RSA_size(rsa), fuzzed_data_provider);

  Blob ciphertext(RSA_size(rsa));
  RSA_public_encrypt(fuzzed_padded_blob.size(), fuzzed_padded_blob.data(),
                     ciphertext.data(), rsa, RSA_NO_PADDING);
  return MutateBlob(ciphertext, /*min_length=*/0, /*max_length=*/RSA_size(rsa),
                    fuzzed_data_provider);
}

}  // namespace

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  static Environment environment;
  // Prevent OpenSSL errors from accumulating in the error queue and leaking the
  // memory across fuzzer executions.
  ScopedOpensslErrorClearer scoped_openssl_error_clearer;

  FuzzedDataProvider fuzzed_data_provider(data, size);

  RSA* const encryption_rsa =
      environment
          .rsa_keys[fuzzed_data_provider.ConsumeIntegralInRange(
              0, Environment::kRsaKeyCount - 1)]
          .get();
  RSA* const decryption_rsa =
      environment
          .rsa_keys[fuzzed_data_provider.ConsumeIntegralInRange(
              0, Environment::kRsaKeyCount - 1)]
          .get();

  // Prepare fuzzed parameters for the tested function, based off real
  // RSA-encoded blobs.
  const Blob plaintext = BlobFromString(
      fuzzed_data_provider.ConsumeRandomLengthString(kMaxPlaintextLength));
  const Blob oaep_label = BlobFromString(
      fuzzed_data_provider.ConsumeRandomLengthString(kMaxOaepLabelLength));
  const Blob fuzzed_ciphertext = FuzzedRsaOaepEncrypt(
      plaintext, oaep_label, encryption_rsa, &fuzzed_data_provider);

  const Blob fuzzed_oaep_label =
      MutateBlob(oaep_label, /*min_length=*/0,
                 /*max_length=*/kMaxOaepLabelLength, &fuzzed_data_provider);

  // Run the fuzzed function.
  SecureBlob decrypted_data;
  if (cryptohome::RsaOaepDecrypt(SecureBlob(fuzzed_ciphertext),
                                 SecureBlob(fuzzed_oaep_label), decryption_rsa,
                                 &decrypted_data)) {
    // Assert that the decryption result must be equal to the plaintext that was
    // encrypted above - it's unrealistic for the fuzzer to find a blob that is
    // a valid ciphertext of some different blob.
    CHECK(SecureBlob(plaintext) == decrypted_data);
  }
  return 0;
}
