cryptohome: Use fscrypt encrypted container for encrypted reboot vault

Use the fscrypt container for the encrypted reboot vault.

BUG=b:172344853
TEST=platform.EncryptedRebootVault

Change-Id: I65f66db4a3904165b451a2491dbe94cc39731e12
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2579889
Tested-by: Sarthak Kukreti <sarthakkukreti@chromium.org>
Commit-Queue: Sarthak Kukreti <sarthakkukreti@chromium.org>
Reviewed-by: Daniil Lunev <dlunev@chromium.org>
diff --git a/cryptohome/encrypted_reboot_vault/encrypted_reboot_vault.cc b/cryptohome/encrypted_reboot_vault/encrypted_reboot_vault.cc
index 954a33f..f53c679 100644
--- a/cryptohome/encrypted_reboot_vault/encrypted_reboot_vault.cc
+++ b/cryptohome/encrypted_reboot_vault/encrypted_reboot_vault.cc
@@ -6,6 +6,9 @@
 
 #include <cryptohome/cryptolib.h>
 #include <cryptohome/dircrypto_util.h>
+#include <cryptohome/platform.h>
+#include <cryptohome/storage/encrypted_container/encrypted_container.h>
+#include <cryptohome/storage/encrypted_container/filesystem_key.h>
 
 #include <base/files/file_enumerator.h>
 #include <base/files/file_path.h>
@@ -40,12 +43,12 @@
   return true;
 }
 
-bool SaveKey(const brillo::SecureBlob& key) {
+bool SaveKey(const cryptohome::FileSystemKey& 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));
+                  cryptohome::CryptoLib::SecureBlobToHex(key.fek));
 
   std::string store_contents = store.SaveToString();
   if (store_contents.empty() ||
@@ -56,7 +59,8 @@
   return true;
 }
 
-brillo::SecureBlob RetrieveKey() {
+cryptohome::FileSystemKey RetrieveKey() {
+  cryptohome::FileSystemKey key;
   base::FileEnumerator pmsg_ramoops_enumerator(
       base::FilePath(kPstorePath), true /* recursive */,
       base::FileEnumerator::FILES, kPmsgKeystoreRamoopsPathDesc);
@@ -66,31 +70,30 @@
     brillo::KeyValueStore store;
     std::string val;
     if (store.Load(ramoops_file) && store.GetString(kEncryptionKeyTag, &val)) {
-      auto encryption_key =
-          brillo::SecureHexToSecureBlob(brillo::SecureBlob(val));
+      key.fek = brillo::SecureHexToSecureBlob(brillo::SecureBlob(val));
       base::DeleteFile(ramoops_file);
       // 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))
+      if (!SaveKey(key))
         LOG(WARNING) << "Failed to store key for next reboot.";
-      return encryption_key;
+      return key;
     }
   }
-  return brillo::SecureBlob();
+  return key;
 }
 
 }  // 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;
-  }
+  cryptohome::FileSystemKeyReference key_reference;
+  key_reference.fek_sig = brillo::SecureBlob(kEncryptionKeyTag);
+
+  encrypted_container_ = cryptohome::EncryptedContainer::Generate(
+      cryptohome::EncryptedContainerType::kFscrypt, vault_path_, key_reference,
+      &platform_);
 }
 
 bool EncryptedRebootVault::CreateVault() {
@@ -107,15 +110,10 @@
   PurgeVault();
 
   // Generate encryption key.
-  brillo::SecureBlob transient_encryption_key =
+  cryptohome::FileSystemKey transient_encryption_key;
+  transient_encryption_key.fek =
       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.";
@@ -123,14 +121,8 @@
   }
 
   // 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";
+  if (!encrypted_container_->Setup(transient_encryption_key, /*create=*/true)) {
+    LOG(ERROR) << "Failed to setup encrypted container";
     return false;
   }
 
@@ -145,10 +137,10 @@
 }
 
 bool EncryptedRebootVault::PurgeVault() {
-  if (!dircrypto::RemoveDirectoryKey(key_reference_, vault_path_)) {
+  if (!encrypted_container_->Teardown()) {
     LOG(WARNING) << "Failed to unlink encryption key from keyring.";
   }
-  return base::DeletePathRecursively(vault_path_);
+  return encrypted_container_->Purge();
 }
 
 bool EncryptedRebootVault::UnlockVault() {
@@ -168,30 +160,17 @@
     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()) {
+  cryptohome::FileSystemKey transient_encryption_key = RetrieveKey();
+  if (transient_encryption_key.fek.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_)) {
+  if (!encrypted_container_->Setup(transient_encryption_key,
+                                   /*create=*/false)) {
     LOG(ERROR) << "Failed to add key to keyring.";
     return false;
   }
diff --git a/cryptohome/encrypted_reboot_vault/encrypted_reboot_vault.h b/cryptohome/encrypted_reboot_vault/encrypted_reboot_vault.h
index 77816ab..1591ffc 100644
--- a/cryptohome/encrypted_reboot_vault/encrypted_reboot_vault.h
+++ b/cryptohome/encrypted_reboot_vault/encrypted_reboot_vault.h
@@ -5,12 +5,15 @@
 #ifndef CRYPTOHOME_ENCRYPTED_REBOOT_VAULT_ENCRYPTED_REBOOT_VAULT_H_
 #define CRYPTOHOME_ENCRYPTED_REBOOT_VAULT_ENCRYPTED_REBOOT_VAULT_H_
 
+#include <memory>
 #include <string>
 
 #include <base/files/file_path.h>
 #include <brillo/brillo_export.h>
 
 #include <cryptohome/dircrypto_util.h>
+#include <cryptohome/platform.h>
+#include <cryptohome/storage/encrypted_container/encrypted_container.h>
 
 class EncryptedRebootVault {
  public:
@@ -27,7 +30,8 @@
 
  private:
   base::FilePath vault_path_;
-  dircrypto::KeyReference key_reference_;
+  cryptohome::Platform platform_;
+  std::unique_ptr<cryptohome::EncryptedContainer> encrypted_container_;
 };
 
 #endif  // CRYPTOHOME_ENCRYPTED_REBOOT_VAULT_ENCRYPTED_REBOOT_VAULT_H_