From b742a370124f99ce524fbb12e438d717b4de99b7 Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Tue, 7 Jan 2020 22:47:48 -0700 Subject: [PATCH] Rewrite MemoryStorage --- src/LibHac/Fs/MemoryStorage.cs | 57 +++++++++++++ src/LibHac/Fs/StorageBase.cs | 2 + src/LibHac/FsSystem/MemoryStorage.cs | 118 --------------------------- src/LibHac/Keyset.cs | 7 +- 4 files changed, 60 insertions(+), 124 deletions(-) create mode 100644 src/LibHac/Fs/MemoryStorage.cs delete mode 100644 src/LibHac/FsSystem/MemoryStorage.cs diff --git a/src/LibHac/Fs/MemoryStorage.cs b/src/LibHac/Fs/MemoryStorage.cs new file mode 100644 index 00000000..46a36c88 --- /dev/null +++ b/src/LibHac/Fs/MemoryStorage.cs @@ -0,0 +1,57 @@ +using System; + +namespace LibHac.Fs +{ + public class MemoryStorage : StorageBase + { + private byte[] StorageBuffer { get; } + + public MemoryStorage(byte[] buffer) + { + StorageBuffer = buffer; + } + + protected override Result ReadImpl(long offset, Span destination) + { + if (destination.Length == 0) + return Result.Success; + + if (!IsRangeValid(offset, destination.Length, StorageBuffer.Length)) + return ResultFs.ValueOutOfRange.Log(); + + StorageBuffer.AsSpan((int)offset, destination.Length).CopyTo(destination); + + return Result.Success; + } + + protected override Result WriteImpl(long offset, ReadOnlySpan source) + { + if (source.Length == 0) + return Result.Success; + + if (!IsRangeValid(offset, source.Length, StorageBuffer.Length)) + return ResultFs.ValueOutOfRange.Log(); + + source.CopyTo(StorageBuffer.AsSpan((int)offset)); + + return Result.Success; + } + + protected override Result FlushImpl() + { + return Result.Success; + } + + protected override Result SetSizeImpl(long size) + { + return ResultFs.UnsupportedOperationInMemoryStorageSetSize.Log(); + } + + protected override Result GetSizeImpl(out long size) + { + size = StorageBuffer.Length; + + return Result.Success; + } + } +} diff --git a/src/LibHac/Fs/StorageBase.cs b/src/LibHac/Fs/StorageBase.cs index f764494f..1ea1789b 100644 --- a/src/LibHac/Fs/StorageBase.cs +++ b/src/LibHac/Fs/StorageBase.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; using System.Threading; namespace LibHac.Fs @@ -77,6 +78,7 @@ namespace LibHac.Fs protected virtual void Dispose(bool disposing) { } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsRangeValid(long offset, long size, long totalSize) { return offset >= 0 && size >= 0 && size <= totalSize && offset <= totalSize - size; diff --git a/src/LibHac/FsSystem/MemoryStorage.cs b/src/LibHac/FsSystem/MemoryStorage.cs deleted file mode 100644 index b655b885..00000000 --- a/src/LibHac/FsSystem/MemoryStorage.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System; -using LibHac.Fs; - -namespace LibHac.FsSystem -{ - public class MemoryStorage : StorageBase - { - private byte[] _buffer; - private int _start; - private int _length; - private int _capacity; - private bool _isExpandable; - - public MemoryStorage() : this(0) { } - - public MemoryStorage(int capacity) - { - if (capacity < 0) throw new ArgumentOutOfRangeException(nameof(capacity), "Argument must be positive"); - - _capacity = capacity; - _isExpandable = true; - _buffer = new byte[capacity]; - } - - public MemoryStorage(byte[] buffer) : this(buffer, 0, buffer.Length) { } - - public MemoryStorage(byte[] buffer, int index, int count) - { - if (buffer == null) throw new NullReferenceException(nameof(buffer)); - if (index < 0) throw new ArgumentOutOfRangeException(nameof(index), "Value must be non-negative."); - if (count < 0) throw new ArgumentOutOfRangeException(nameof(count), "Value must be non-negative."); - if (buffer.Length - index < count) throw new ArgumentException("Length, index and count parameters are invalid."); - - _buffer = buffer; - _start = index; - _length = count; - _capacity = count; - _isExpandable = false; - } - - protected override Result ReadImpl(long offset, Span destination) - { - if (!IsRangeValid(offset, destination.Length, _length)) - return ResultFs.ValueOutOfRange.Log(); - - _buffer.AsSpan((int)(_start + offset), destination.Length).CopyTo(destination); - - return Result.Success; - } - - protected override Result WriteImpl(long offset, ReadOnlySpan source) - { - if (!IsRangeValid(offset, source.Length, _length)) - return ResultFs.ValueOutOfRange.Log(); - - long requiredCapacity = _start + offset + source.Length; - - if (requiredCapacity > _length) - { - if (requiredCapacity > _capacity) EnsureCapacity(requiredCapacity); - _length = (int)(requiredCapacity - _start); - } - - source.CopyTo(_buffer.AsSpan((int)(_start + offset), source.Length)); - - return Result.Success; - } - - public byte[] ToArray() - { - var array = new byte[_length]; - Buffer.BlockCopy(_buffer, _start, array, 0, _length); - return array; - } - - // returns a bool saying whether we allocated a new array. - private void EnsureCapacity(long value) - { - if (value < 0 || value > int.MaxValue) throw new ArgumentOutOfRangeException(nameof(value)); - if (value <= _capacity) return; - - long newCapacity = Math.Max(value, 256); - newCapacity = Math.Max(newCapacity, _capacity * 2); - - SetCapacity((int)Math.Min(newCapacity, int.MaxValue)); - } - - private void SetCapacity(int value) - { - if (value < _length) - throw new ArgumentOutOfRangeException(nameof(value), "Capacity is smaller than the current length."); - - if (!_isExpandable && value != _capacity) throw new NotSupportedException("MemoryStorage is not expandable."); - - if (_isExpandable && value != _capacity) - { - var newBuffer = new byte[value]; - Buffer.BlockCopy(_buffer, 0, newBuffer, 0, _length); - - _buffer = newBuffer; - _capacity = value; - } - } - - protected override Result FlushImpl() => Result.Success; - - protected override Result GetSizeImpl(out long size) - { - size = _length; - return Result.Success; - } - - protected override Result SetSizeImpl(long size) - { - return ResultFs.UnsupportedOperationInMemoryStorageSetSize.Log(); - } - } -} diff --git a/src/LibHac/Keyset.cs b/src/LibHac/Keyset.cs index 53385def..a818d6b6 100644 --- a/src/LibHac/Keyset.cs +++ b/src/LibHac/Keyset.cs @@ -6,7 +6,6 @@ using System.Security.Cryptography; using System.Text; using LibHac.Fs; using LibHac.FsService; -using LibHac.FsSystem; using LibHac.Spl; using Aes = LibHac.Crypto.Aes; @@ -305,11 +304,7 @@ namespace LibHac Array.Copy(EncryptedKeyblobs[i], 0x10, counter, 0, 0x10); - using (var keyblobDec = new Aes128CtrStorage( - new MemoryStorage(EncryptedKeyblobs[i], 0x20, Keyblobs[i].Length), KeyblobKeys[i], counter, false)) - { - keyblobDec.Read(0, Keyblobs[i]).ThrowIfFailure(); - } + Aes.DecryptCtr128(EncryptedKeyblobs[i].AsSpan(0x20), Keyblobs[i], KeyblobKeys[i], counter); } }