mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Use Sha256Generator throughout the library
This commit is contained in:
parent
1efcf3327c
commit
e18481b3b7
11 changed files with 76 additions and 59 deletions
|
@ -2,7 +2,7 @@
|
|||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using System.Security.Cryptography;
|
||||
using LibHac.Crypto;
|
||||
|
||||
namespace LibHac.Compatibility
|
||||
{
|
||||
|
@ -17,7 +17,6 @@ namespace LibHac.Compatibility
|
|||
const int saltOffset = hashOffset - digestLen;
|
||||
const int padEnd = saltOffset - 1;
|
||||
|
||||
SHA256 sha = SHA256.Create();
|
||||
var message = new byte[rsaLen];
|
||||
|
||||
BigInteger decInt = BigInteger.ModPow(CryptoOld.GetBigInteger(signature), new BigInteger(65537), CryptoOld.GetBigInteger(modulus));
|
||||
|
@ -33,9 +32,12 @@ namespace LibHac.Compatibility
|
|||
|
||||
ref byte seed = ref hashBuf[0x23];
|
||||
|
||||
Span<byte> digestBuffer = stackalloc byte[Sha256.DigestSize];
|
||||
|
||||
for (int i = 0; i < hashOffset; i += 0x20)
|
||||
{
|
||||
Util.XorArrays(message.AsSpan(i, digestLen), sha.ComputeHash(hashBuf));
|
||||
Sha256.GenerateSha256Hash(hashBuf, digestBuffer);
|
||||
Util.XorArrays(message.AsSpan(i, digestLen), digestBuffer);
|
||||
seed++;
|
||||
}
|
||||
|
||||
|
@ -46,14 +48,21 @@ namespace LibHac.Compatibility
|
|||
return false;
|
||||
}
|
||||
|
||||
var prefix = new byte[8];
|
||||
byte[] digest = sha.ComputeHash(data);
|
||||
Span<byte> prefix = stackalloc byte[8];
|
||||
Span<byte> digest = stackalloc byte[Sha256.DigestSize];
|
||||
|
||||
sha.TransformBlock(prefix, 0, prefix.Length, null, 0);
|
||||
sha.TransformBlock(digest, 0, digestLen, null, 0);
|
||||
sha.TransformFinalBlock(message, saltOffset, digestLen);
|
||||
Sha256.GenerateSha256Hash(data, digest);
|
||||
|
||||
return Util.SpansEqual(hashBuf.AsSpan(0, 0x20), sha.Hash);
|
||||
IHash sha2 = Sha256.CreateSha256Generator();
|
||||
sha2.Initialize();
|
||||
|
||||
sha2.Update(prefix);
|
||||
sha2.Update(digest);
|
||||
sha2.Update(message.AsSpan(saltOffset, digestLen));
|
||||
|
||||
sha2.GetHash(digest);
|
||||
|
||||
return Util.SpansEqual(hashBuf.AsSpan(0, 0x20), digest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,10 @@ namespace LibHac.Crypto
|
|||
{
|
||||
public const int DigestSize = 0x20;
|
||||
|
||||
/// <summary>
|
||||
/// Creates an uninitialized SHA-256 <see cref="IHash"/> object.
|
||||
/// </summary>
|
||||
/// <returns> The new uninitialized SHA-256 <see cref="IHash"/> object.</returns>
|
||||
public static IHash CreateSha256Generator()
|
||||
{
|
||||
return new Sha256Generator();
|
||||
|
|
|
@ -9,25 +9,6 @@ namespace LibHac
|
|||
public static class CryptoOld
|
||||
{
|
||||
internal const int Aes128Size = 0x10;
|
||||
internal const int Sha256DigestSize = 0x20;
|
||||
|
||||
public static Validity CheckMemoryHashTable(byte[] data, byte[] hash, int offset, int count)
|
||||
{
|
||||
Validity comp;
|
||||
using (SHA256 sha = SHA256.Create())
|
||||
{
|
||||
comp = Util.ArraysEqual(hash, sha.ComputeHash(data, offset, count)) ? Validity.Valid : Validity.Invalid;
|
||||
}
|
||||
return comp;
|
||||
}
|
||||
|
||||
public static byte[] ComputeSha256(byte[] data, int offset, int count)
|
||||
{
|
||||
using (SHA256 sha = SHA256.Create())
|
||||
{
|
||||
return sha.ComputeHash(data, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DecryptEcb(byte[] key, byte[] src, int srcIndex, byte[] dest, int destIndex, int length)
|
||||
{
|
||||
|
@ -172,7 +153,7 @@ namespace LibHac
|
|||
public static Validity Rsa2048PssVerify(byte[] data, byte[] signature, byte[] modulus)
|
||||
{
|
||||
#if NETFRAMEWORK
|
||||
if (Compatibility.Env.IsMono)
|
||||
if (!Compatibility.Env.IsMono)
|
||||
{
|
||||
return Compatibility.Rsa.Rsa2048PssVerifyMono(data, signature, modulus)
|
||||
? Validity.Valid
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Buffers;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using LibHac.Crypto;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSystem.Save;
|
||||
|
||||
|
@ -18,7 +18,7 @@ namespace LibHac.FsSystem
|
|||
private byte[] Salt { get; }
|
||||
private IntegrityStorageType Type { get; }
|
||||
|
||||
private readonly SHA256 _hash = SHA256.Create();
|
||||
private readonly IHash _hash = Sha256.CreateSha256Generator();
|
||||
private readonly object _locker = new object();
|
||||
|
||||
public IntegrityVerificationStorage(IntegrityVerificationInfo info, IStorage hashStorage,
|
||||
|
@ -170,13 +170,13 @@ namespace LibHac.FsSystem
|
|||
|
||||
if (Type == IntegrityStorageType.Save)
|
||||
{
|
||||
_hash.TransformBlock(Salt, 0, Salt.Length, null, 0);
|
||||
_hash.Update(Salt);
|
||||
}
|
||||
|
||||
_hash.TransformBlock(buffer, offset, count, null, 0);
|
||||
_hash.TransformFinalBlock(buffer, 0, 0);
|
||||
_hash.Update(buffer.AsSpan(offset, count));
|
||||
|
||||
byte[] hash = _hash.Hash;
|
||||
var hash = new byte[Sha256.DigestSize];
|
||||
_hash.GetHash(hash);
|
||||
|
||||
if (Type == IntegrityStorageType.Save)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.Diagnostics;
|
||||
using LibHac.Crypto;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem.NcaUtils
|
||||
|
@ -98,7 +99,8 @@ namespace LibHac.FsSystem.NcaUtils
|
|||
var data = new byte[size];
|
||||
storage.Read(offset, data).ThrowIfFailure();
|
||||
|
||||
byte[] actualHash = CryptoOld.ComputeSha256(data, 0, data.Length);
|
||||
var actualHash = new byte[Sha256.DigestSize];
|
||||
Sha256.GenerateSha256Hash(data, actualHash);
|
||||
|
||||
if (Util.ArraysEqual(expectedHash, actualHash)) return Validity.Valid;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Crypto;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem.NcaUtils
|
||||
|
@ -163,7 +164,8 @@ namespace LibHac.FsSystem.NcaUtils
|
|||
// ReSharper disable once ImpureMethodCallOnReadonlyValueField
|
||||
Memory<byte> headerData = _header.Slice(offset, NcaHeaderStruct.FsHeaderSize);
|
||||
|
||||
byte[] actualHash = CryptoOld.ComputeSha256(headerData.ToArray(), 0, NcaHeaderStruct.FsHeaderSize);
|
||||
Span<byte> actualHash = stackalloc byte[Sha256.DigestSize];
|
||||
Sha256.GenerateSha256Hash(headerData.Span, actualHash);
|
||||
|
||||
if (!Util.SpansEqual(expectedHash, actualHash))
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using LibHac.Crypto;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
|
@ -164,7 +165,7 @@ namespace LibHac.FsSystem
|
|||
{
|
||||
HashedRegionSize = reader.ReadInt32();
|
||||
HashedRegionOffset = reader.ReadInt64();
|
||||
Hash = reader.ReadBytes(CryptoOld.Sha256DigestSize);
|
||||
Hash = reader.ReadBytes(Sha256.DigestSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using LibHac.Crypto;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
|
@ -23,7 +23,8 @@ namespace LibHac.FsSystem
|
|||
/// </summary>
|
||||
public PartitionFileSystemBuilder(IFileSystem input)
|
||||
{
|
||||
foreach (DirectoryEntryEx entry in input.EnumerateEntries().OrderBy(x => x.FullPath, StringComparer.Ordinal))
|
||||
foreach (DirectoryEntryEx entry in input.EnumerateEntries().Where(x => x.Type == DirectoryEntryType.File)
|
||||
.OrderBy(x => x.FullPath, StringComparer.Ordinal))
|
||||
{
|
||||
input.OpenFile(out IFile file, entry.FullPath, OpenMode.Read).ThrowIfFailure();
|
||||
|
||||
|
@ -144,22 +145,25 @@ namespace LibHac.FsSystem
|
|||
|
||||
private void CalculateHashes()
|
||||
{
|
||||
using (SHA256 sha = SHA256.Create())
|
||||
IHash sha = Sha256.CreateSha256Generator();
|
||||
|
||||
foreach (Entry entry in Entries)
|
||||
{
|
||||
foreach (Entry entry in Entries)
|
||||
if (entry.HashLength == 0) entry.HashLength = 0x200;
|
||||
|
||||
var data = new byte[entry.HashLength];
|
||||
entry.File.Read(out long bytesRead, entry.HashOffset, data);
|
||||
|
||||
if (bytesRead != entry.HashLength)
|
||||
{
|
||||
if (entry.HashLength == 0) entry.HashLength = 0x200;
|
||||
|
||||
var data = new byte[entry.HashLength];
|
||||
entry.File.Read(out long bytesRead, entry.HashOffset, data);
|
||||
|
||||
if (bytesRead != entry.HashLength)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
entry.Hash = sha.ComputeHash(data);
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
entry.Hash = new byte[Sha256.DigestSize];
|
||||
|
||||
sha.Initialize();
|
||||
sha.Update(data);
|
||||
sha.GetHash(entry.Hash);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using LibHac.Crypto;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem.Save
|
||||
|
@ -81,7 +82,10 @@ namespace LibHac.FsSystem.Save
|
|||
|
||||
MasterHash = storage.Slice(Layout.IvfcMasterHashOffsetA, Layout.IvfcMasterHashSize);
|
||||
|
||||
HeaderHashValidity = CryptoOld.CheckMemoryHashTable(Data, Layout.Hash, 0x300, 0x3d00);
|
||||
Span<byte> actualHeaderHash = stackalloc byte[Sha256.DigestSize];
|
||||
Sha256.GenerateSha256Hash(Data.AsSpan(0x300, 0x3d00), actualHeaderHash);
|
||||
|
||||
HeaderHashValidity = Util.SpansEqual(Layout.Hash, actualHeaderHash) ? Validity.Valid : Validity.Invalid;
|
||||
SignatureValidity = ValidateSignature(keyset);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using LibHac.Crypto;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem.Save
|
||||
|
@ -252,7 +253,9 @@ namespace LibHac.FsSystem.Save
|
|||
headerStream.Position = 0x300;
|
||||
headerStream.Read(hashData, 0, hashData.Length);
|
||||
|
||||
byte[] hash = CryptoOld.ComputeSha256(hashData, 0, hashData.Length);
|
||||
var hash = new byte[Sha256.DigestSize];
|
||||
Sha256.GenerateSha256Hash(hashData, hash);
|
||||
|
||||
headerStream.Position = 0x108;
|
||||
headerStream.Write(hash, 0, hash.Length);
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using LibHac.Crypto;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac
|
||||
|
@ -99,8 +100,8 @@ namespace LibHac
|
|||
Array.Reverse(AesCbcIv);
|
||||
RootPartitionOffset = reader.ReadInt64();
|
||||
RootPartitionHeaderSize = reader.ReadInt64();
|
||||
RootPartitionHeaderHash = reader.ReadBytes(CryptoOld.Sha256DigestSize);
|
||||
InitialDataHash = reader.ReadBytes(CryptoOld.Sha256DigestSize);
|
||||
RootPartitionHeaderHash = reader.ReadBytes(Sha256.DigestSize);
|
||||
InitialDataHash = reader.ReadBytes(Sha256.DigestSize);
|
||||
SelSec = reader.ReadInt32();
|
||||
SelT1Key = reader.ReadInt32();
|
||||
SelKey = reader.ReadInt32();
|
||||
|
@ -128,10 +129,16 @@ namespace LibHac
|
|||
}
|
||||
}
|
||||
|
||||
ImageHash = CryptoOld.ComputeSha256(sigData, 0, sigData.Length);
|
||||
ImageHash = new byte[Sha256.DigestSize];
|
||||
Sha256.GenerateSha256Hash(sigData, ImageHash);
|
||||
|
||||
reader.BaseStream.Position = RootPartitionOffset;
|
||||
PartitionFsHeaderValidity = CryptoOld.CheckMemoryHashTable(reader.ReadBytes((int)RootPartitionHeaderSize), RootPartitionHeaderHash, 0, (int)RootPartitionHeaderSize);
|
||||
byte[] headerBytes = reader.ReadBytes((int) RootPartitionHeaderSize);
|
||||
|
||||
Span<byte> actualHeaderHash = stackalloc byte[Sha256.DigestSize];
|
||||
Sha256.GenerateSha256Hash(headerBytes, actualHeaderHash);
|
||||
|
||||
PartitionFsHeaderValidity = Util.SpansEqual(RootPartitionHeaderHash, actualHeaderHash) ? Validity.Valid : Validity.Invalid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue