// Copyright 2020 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 "cryptohome/encrypted_reboot_vault/encrypted_reboot_vault.h"

#include <cryptohome/cryptolib.h>
#include <cryptohome/dircrypto_util.h>

#include <base/files/file_enumerator.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <brillo/key_value_store.h>

namespace {
// Pstore-pmsg path.
const char kPmsgDevicePath[] = "/dev/pmsg0";
// There can be multiple pmsg ramoops entries.
const char kPmsgKeystoreRamoopsPathDesc[] = "pmsg-ramoops-*";
const char kExt4DircryptoSupportedPath[] = "/sys/fs/ext4/features/encryption";
const char kEncryptedRebootVaultPath[] = "/mnt/stateful_partition/reboot_vault";
// Pstore path.
const char kPstorePath[] = "/sys/fs/pstore";
// Key tag to retrieve the key from pstore-pmsg.
const char kEncryptionKeyTag[] = "pmsg-key";
// Encryption key size.
const size_t kEncryptionKeySize = 64;

bool IsSupported() {
  if (!base::PathExists(base::FilePath(kPmsgDevicePath))) {
    LOG(ERROR) << "pmsg0 not enabled.";
    return false;
  }

  // Check if we can create an encrypted vault.
  if (!base::PathExists(base::FilePath(kExt4DircryptoSupportedPath))) {
    LOG(ERROR) << "ext4 directory encryption not supported.";
    return false;
  }
  return true;
}

bool SaveKey(const brillo::SecureBlob& key) {
  // Do not use store.Save() since it uses WriteFileAtomically() which will
  // fail on /dev/pmsg0.
  brillo::KeyValueStore store;
  store.SetString(kEncryptionKeyTag,
      cryptohome::CryptoLib::SecureBlobToHex(key));

  std::string store_contents = store.SaveToString();
  if (store_contents.empty() ||
      !base::WriteFile(base::FilePath(kPmsgDevicePath), store_contents.data(),
                       store_contents.size())) {
    return false;
  }
  return true;
}

brillo::SecureBlob RetrieveKey() {
  base::FileEnumerator pmsg_ramoops_enumerator(
      base::FilePath(kPstorePath), true /* recursive */,
      base::FileEnumerator::FILES, kPmsgKeystoreRamoopsPathDesc);

  for (base::FilePath ramoops_file = pmsg_ramoops_enumerator.Next();
      !ramoops_file.empty(); ramoops_file = pmsg_ramoops_enumerator.Next()) {
    brillo::KeyValueStore store;
    std::string val;
    if (store.Load(ramoops_file) && store.GetString(kEncryptionKeyTag, &val)) {
      auto encryption_key =
          brillo::SecureHexToSecureBlob(brillo::SecureBlob(val));
      base::DeleteFile(ramoops_file, false /* recursive */);
      // SaveKey stores the key again into pstore-pmsg on every boot since the
      // pstore object isn't persistent. Since the pstore object is always
      // stored in RAM on ChromiumOS, it is cleared the next time the device
      // shuts down or loses power.
      if (!SaveKey(encryption_key))
        LOG(WARNING) << "Failed to store key for next reboot.";
      return encryption_key;
    }
  }
  return brillo::SecureBlob();
}

}  // namespace

EncryptedRebootVault::EncryptedRebootVault()
    : vault_path_(base::FilePath(kEncryptedRebootVaultPath)) {
  if (dircrypto::CheckFscryptKeyIoctlSupport()) {
    key_reference_.policy_version = FSCRYPT_POLICY_V2;
  } else {
    key_reference_.reference = brillo::SecureBlob(kEncryptionKeyTag);
    key_reference_.policy_version = FSCRYPT_POLICY_V1;
  }
}

bool EncryptedRebootVault::CreateVault() {
  if (!IsSupported()) {
    LOG(ERROR) << "EncryptedRebootVault not supported";
    return false;
  }

  base::ScopedClosureRunner reset_vault(
      base::Bind(base::IgnoreResult(&EncryptedRebootVault::PurgeVault),
          base::Unretained(this)));

  // Remove the existing vault.
  PurgeVault();

  // Generate encryption key.
  brillo::SecureBlob transient_encryption_key =
      cryptohome::CryptoLib::CreateSecureRandomBlob(kEncryptionKeySize);

  // The key descriptor needs to be exactly 8 bytes for v1 encryption policies.
  if (!dircrypto::AddDirectoryKey(transient_encryption_key, &key_reference_)) {
    LOG(ERROR) << "Failed to add pmsg-key";
    return false;
  }

  // Store key into pmsg. If it fails, we bail out.
  if (!SaveKey(transient_encryption_key)) {
    LOG(ERROR) << "Failed to store transient encryption key to pmsg.";
    return false;
  }

  // Set up the encrypted reboot vault.
  if (!base::CreateDirectory(vault_path_)) {
    LOG(ERROR) << "Failed to create directory";
    return false;
  }

  // Set the fscrypt context for the directory.
  if (!dircrypto::SetDirectoryKey(vault_path_, key_reference_)) {
    LOG(ERROR) << "Failed to set directory key";
    return false;
  }

  ignore_result(reset_vault.Release());
  return true;
}

bool EncryptedRebootVault::Validate() {
  return base::PathExists(vault_path_) &&
         dircrypto::GetDirectoryKeyState(vault_path_) ==
             dircrypto::KeyState::ENCRYPTED;
}

bool EncryptedRebootVault::PurgeVault() {
  if (!dircrypto::RemoveDirectoryKey(key_reference_, vault_path_)) {
    LOG(WARNING) << "Failed to unlink encryption key from keyring.";
  }
  return base::DeleteFile(vault_path_, true /* recursively */);
}

bool EncryptedRebootVault::UnlockVault() {
  if (!IsSupported()) {
    LOG(ERROR) << "EncryptedRebootVault depends on pstore-pmsg to pass the "
                  "encryption key. Enable CONFIG_PSTORE_PMSG";
    return false;
  }

  // We reset the vault if we fail to unlock it for any reason.
  base::ScopedClosureRunner reset_vault(
      base::Bind(base::IgnoreResult(&EncryptedRebootVault::PurgeVault),
          base::Unretained(this)));

  if (!Validate()) {
    LOG(ERROR) << "Invalid vault; purging.";
    return false;
  }

  // If the vault exists, get the policy version from the directory.
  switch (dircrypto::GetDirectoryPolicyVersion(vault_path_)) {
    case FSCRYPT_POLICY_V1:
      key_reference_.policy_version = FSCRYPT_POLICY_V1;
      key_reference_.reference = brillo::SecureBlob(kEncryptionKeyTag);
      break;
    case FSCRYPT_POLICY_V2:
      key_reference_.policy_version = FSCRYPT_POLICY_V2;
      break;
    default:
      LOG(ERROR) << "Failed to get policy version for directory";
      return false;
  }

  // Retrieve key.
  brillo::SecureBlob transient_encryption_key = RetrieveKey();
  if (transient_encryption_key.empty()) {
    LOG(INFO) << "No valid key found: the device might have booted up from a "
                 "shutdown.";
    return false;
  }

  // Unlock vault.
  if (!dircrypto::AddDirectoryKey(transient_encryption_key, &key_reference_)) {
    LOG(ERROR) << "Failed to add key to keyring.";
    return false;
  }

  ignore_result(reset_vault.Release());
  return true;
}
