Ejemplo n.º 1
0
        public AesXtsFile(OpenMode mode, IFile baseFile, U8String path, ReadOnlySpan <byte> kekSeed, ReadOnlySpan <byte> verificationKey, int blockSize)
        {
            Mode            = mode;
            BaseFile        = baseFile;
            Path            = path;
            KekSeed         = kekSeed.ToArray();
            VerificationKey = verificationKey.ToArray();
            BlockSize       = blockSize;

            Header = new AesXtsFileHeader(BaseFile);

            baseFile.GetSize(out long fileSize).ThrowIfFailure();

            if (!Header.TryDecryptHeader(Path.ToString(), KekSeed, VerificationKey))
            {
                ThrowHelper.ThrowResult(ResultFs.AesXtsFileHeaderInvalidKeys.Value, "NAX0 key derivation failed.");
            }

            if (HeaderLength + Utilities.AlignUp(Header.Size, 0x10) > fileSize)
            {
                ThrowHelper.ThrowResult(ResultFs.AesXtsFileTooShort.Value, "NAX0 key derivation failed.");
            }

            var fileStorage = new FileStorage2(baseFile);
            var encStorage  = new SubStorage(fileStorage, HeaderLength, fileSize - HeaderLength);

            encStorage.SetResizable(true);

            BaseStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Header.DecryptedKey1, Header.DecryptedKey2, BlockSize, true), 4, true);
        }
Ejemplo n.º 2
0
        private Result Initialize(U8Span rootPath)
        {
            if (StringUtils.GetLength(rootPath, PathTools.MaxPathLength + 1) > PathTools.MaxPathLength)
            {
                return(ResultFs.TooLongPath.Log());
            }

            Span <byte> normalizedPath = stackalloc byte[PathTools.MaxPathLength + 2];

            Result rc = PathTool.Normalize(normalizedPath, out long normalizedPathLen, rootPath, PreserveUnc, false);

            if (rc.IsFailure())
            {
                return(rc);
            }

            // Ensure a trailing separator
            if (!PathTool.IsSeparator(normalizedPath[(int)normalizedPathLen - 1]))
            {
                Debug.Assert(normalizedPathLen + 2 <= normalizedPath.Length);

                normalizedPath[(int)normalizedPathLen]     = StringTraits.DirectorySeparator;
                normalizedPath[(int)normalizedPathLen + 1] = StringTraits.NullTerminator;
                normalizedPathLen++;
            }

            var buffer = new byte[normalizedPathLen + 1];

            normalizedPath.Slice(0, (int)normalizedPathLen).CopyTo(buffer);
            RootPath = new U8String(buffer);

            return(Result.Success);
        }
Ejemplo n.º 3
0
 public AesXtsDirectory(IFileSystem baseFs, IDirectory baseDir, U8String path, OpenDirectoryMode mode)
 {
     BaseFileSystem = baseFs;
     BaseDirectory  = baseDir;
     Mode           = mode;
     Path           = path;
 }
Ejemplo n.º 4
0
        public Result OpenContentStorageFileSystem(out IFileSystem fileSystem, ContentStorageId storageId)
        {
            fileSystem = default;

            U8String    contentDirPath = default;
            IFileSystem baseFileSystem = default;
            bool        isEncrypted    = false;
            Result      rc;

            switch (storageId)
            {
            case ContentStorageId.System:
                rc             = OpenBisFileSystem(out baseFileSystem, string.Empty, BisPartitionId.System);
                contentDirPath = $"/{ContentDirectoryName}".ToU8String();
                break;

            case ContentStorageId.User:
                rc             = OpenBisFileSystem(out baseFileSystem, string.Empty, BisPartitionId.User);
                contentDirPath = $"/{ContentDirectoryName}".ToU8String();
                break;

            case ContentStorageId.SdCard:
                rc             = OpenSdCardFileSystem(out baseFileSystem);
                contentDirPath = $"/{NintendoDirectoryName}/{ContentDirectoryName}".ToU8String();
                isEncrypted    = true;
                break;

            default:
                rc = ResultFs.InvalidArgument.Log();
                break;
            }

            if (rc.IsFailure())
            {
                return(rc);
            }

            rc = baseFileSystem.EnsureDirectoryExists(contentDirPath.ToString());
            if (rc.IsFailure())
            {
                return(rc);
            }

            rc = FsCreators.SubDirectoryFileSystemCreator.Create(out IFileSystem subDirFileSystem,
                                                                 baseFileSystem, contentDirPath);
            if (rc.IsFailure())
            {
                return(rc);
            }

            if (!isEncrypted)
            {
                fileSystem = subDirFileSystem;
                return(Result.Success);
            }

            return(FsCreators.EncryptedFileSystemCreator.Create(out fileSystem, subDirFileSystem,
                                                                EncryptedFsKeyId.Content, SdEncryptionSeed));
        }
Ejemplo n.º 5
0
            public Result GenerateCommonMountName(Span <byte> nameBuffer)
            {
                U8String mountName = GetContentStorageMountName(StorageId);

                int length = StringUtils.Copy(nameBuffer, mountName);

                nameBuffer[length]     = (byte)':';
                nameBuffer[length + 1] = 0;

                return(Result.Success);
            }
Ejemplo n.º 6
0
        public static void NormalizePathU8TooShortDest(string path, string expected, int destSize)
        {
            U8String u8Path = path.ToU8String();

            Span <byte> buffer = stackalloc byte[destSize];

            Result rc = PathTools.Normalize(buffer, out int normalizedLength, u8Path, false);

            string actual = StringUtils.Utf8ZToString(buffer);

            Assert.Equal(ResultFs.TooLongPath, rc);
            Assert.Equal(Math.Max(0, destSize - 1), normalizedLength);
            Assert.Equal(expected, actual);
        }
Ejemplo n.º 7
0
        public static void NormalizePathU8MountName(string path, string expected, Result expectedResult)
        {
            U8String    u8Path = path.ToU8String();
            Span <byte> buffer = stackalloc byte[0x301];

            Result rc = PathTools.Normalize(buffer, out _, u8Path, true);

            string actual = StringUtils.Utf8ZToString(buffer);

            Assert.Equal(expectedResult, rc);
            if (expectedResult == Result.Success)
            {
                Assert.Equal(expected, actual);
            }
        }
Ejemplo n.º 8
0
            public Result Initialize(FileSystemClient fsClient, U8String mountName, SaveDataSpaceId spaceId,
                                     ulong saveDataId)
            {
                FsClient  = fsClient;
                MountName = mountName;

                FsClient.DisableAutoSaveDataCreation();

                Result rc = FsClient.MountSystemSaveData(MountName, spaceId, saveDataId);

                if (rc.IsFailure())
                {
                    if (ResultFs.TargetNotFound.Includes(rc))
                    {
                        rc = FsClient.CreateSystemSaveData(spaceId, saveDataId, TitleId.Zero, 0xC0000, 0xC0000, 0);
                        if (rc.IsFailure())
                        {
                            return(rc);
                        }

                        rc = FsClient.MountSystemSaveData(MountName, spaceId, saveDataId);
                        if (rc.IsFailure())
                        {
                            return(rc);
                        }
                    }
                    else
                    {
                        if (ResultFs.SignedSystemPartitionDataCorrupted.Includes(rc))
                        {
                            return(rc);
                        }
                        if (!ResultFs.DataCorrupted.Includes(rc))
                        {
                            return(rc);
                        }

                        if (spaceId == SaveDataSpaceId.SdSystem)
                        {
                            return(rc);
                        }

                        rc = FsClient.DeleteSaveData(spaceId, saveDataId);
                        if (rc.IsFailure())
                        {
                            return(rc);
                        }

                        rc = FsClient.CreateSystemSaveData(spaceId, saveDataId, TitleId.Zero, 0xC0000, 0xC0000, 0);
                        if (rc.IsFailure())
                        {
                            return(rc);
                        }

                        rc = FsClient.MountSystemSaveData(MountName, spaceId, saveDataId);
                        if (rc.IsFailure())
                        {
                            return(rc);
                        }
                    }
                }

                IsMounted = true;

                return(Result.Success);
            }
Ejemplo n.º 9
0
 public KeyValueDatabase(FileSystemClient fsClient, U8Span fileName)
 {
     FsClient = fsClient;
     FileName = fileName.ToU8String();
 }