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); }
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); }
public AesXtsDirectory(IFileSystem baseFs, IDirectory baseDir, U8String path, OpenDirectoryMode mode) { BaseFileSystem = baseFs; BaseDirectory = baseDir; Mode = mode; Path = path; }
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)); }
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); }
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); }
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); } }
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); }
public KeyValueDatabase(FileSystemClient fsClient, U8Span fileName) { FsClient = fsClient; FileName = fileName.ToU8String(); }