From cd4530f29c6a4ffd1b023105350b0440fa63f47b Mon Sep 17 00:00:00 2001
From: Alex Barney <thealexbarney@gmail.com>
Date: Tue, 17 Aug 2021 10:46:52 -0700
Subject: Always use an all-zeros key for AES-XTS file systems (#2561)

---
 .../FileSystem/EncryptedFileSystemCreator.cs       | 62 ++++++++++++++++++++++
 1 file changed, 62 insertions(+)
 create mode 100644 Ryujinx.HLE/FileSystem/EncryptedFileSystemCreator.cs

(limited to 'Ryujinx.HLE/FileSystem/EncryptedFileSystemCreator.cs')

diff --git a/Ryujinx.HLE/FileSystem/EncryptedFileSystemCreator.cs b/Ryujinx.HLE/FileSystem/EncryptedFileSystemCreator.cs
new file mode 100644
index 00000000..aaa80044
--- /dev/null
+++ b/Ryujinx.HLE/FileSystem/EncryptedFileSystemCreator.cs
@@ -0,0 +1,62 @@
+using LibHac;
+using LibHac.Common;
+using LibHac.Fs;
+using LibHac.Fs.Fsa;
+using LibHac.FsSrv.FsCreator;
+using LibHac.FsSystem;
+
+namespace Ryujinx.HLE.FileSystem
+{
+    public class EncryptedFileSystemCreator : IEncryptedFileSystemCreator
+    {
+        public EncryptedFileSystemCreator() { }
+
+        public Result Create(out ReferenceCountedDisposable<IFileSystem> encryptedFileSystem, ReferenceCountedDisposable<IFileSystem> baseFileSystem,
+            EncryptedFsKeyId keyId, in EncryptionSeed encryptionSeed)
+        {
+            UnsafeHelpers.SkipParamInit(out encryptedFileSystem);
+
+            if (keyId < EncryptedFsKeyId.Save || keyId > EncryptedFsKeyId.CustomStorage)
+            {
+                return ResultFs.InvalidArgument.Log();
+            }
+
+            // Force all-zero keys for now since people can open the emulator with different keys or sd seeds sometimes
+            var fs = new AesXtsFileSystem(baseFileSystem, new byte[0x32], 0x4000);
+            var aesFileSystem = new ReferenceCountedDisposable<IFileSystem>(fs);
+
+            // This wrapper will handle deleting files that were created with different keys
+            var wrappedFs = new ChangedEncryptionHandlingFileSystem(aesFileSystem);
+            encryptedFileSystem = new ReferenceCountedDisposable<IFileSystem>(wrappedFs);
+
+            return Result.Success;
+        }
+    }
+
+    public class ChangedEncryptionHandlingFileSystem : ForwardingFileSystem
+    {
+        public ChangedEncryptionHandlingFileSystem(ReferenceCountedDisposable<IFileSystem> baseFileSystem) : base(baseFileSystem) { }
+
+        protected override Result DoOpenFile(out IFile file, U8Span path, OpenMode mode)
+        {
+            UnsafeHelpers.SkipParamInit(out file);
+
+            try
+            {
+                return base.DoOpenFile(out file, path, mode);
+            }
+            catch (HorizonResultException ex)
+            {
+                if (ResultFs.AesXtsFileHeaderInvalidKeys.Includes(ex.ResultValue))
+                {
+                    Result rc = DeleteFile(path);
+                    if (rc.IsFailure()) return rc;
+
+                    return base.DoOpenFile(out file, path, mode);
+                }
+
+                throw;
+            }
+        }
+    }
+}
-- 
cgit v1.2.3-70-g09d2