remove unused code, fix ps1 multi-disc gen `__sce_ebootpbp` failed.
This commit is contained in:
parent
299b042dd9
commit
c96b43031a
|
@ -369,7 +369,7 @@ namespace PbpResign
|
|||
AMCTRL.sceDrmBBCipherInit(out var ckey, 1, 2, npHdr.HeaderKey, vkey, 0);
|
||||
AMCTRL.sceDrmBBCipherUpdate(ref ckey, psarBuff[0x40..], 0x60);
|
||||
AMCTRL.sceDrmBBCipherFinal(ref ckey);
|
||||
npHdr = Utils.AsRef<NpUmdImgHdr>(psarBuff);
|
||||
npHdr = MemoryMarshal.AsRef<NpUmdImgHdr>(psarBuff);
|
||||
|
||||
var lbasize = npHdr.Body.LbaEnd - npHdr.Body.LbaStart + 1;
|
||||
if (npHdr.BlockBasis == 0)
|
||||
|
@ -1059,7 +1059,7 @@ namespace PbpResign
|
|||
return false;
|
||||
}
|
||||
|
||||
ref var npHdr = ref Utils.AsRef<NpUmdImgHdr>(psarBuff);
|
||||
ref var npHdr = ref MemoryMarshal.AsRef<NpUmdImgHdr>(psarBuff);
|
||||
|
||||
if (npHdr.Magic0 == 0x4d55504e && npHdr.Magic1 == 0x474d4944)
|
||||
{
|
||||
|
@ -1189,7 +1189,7 @@ namespace PbpResign
|
|||
return;
|
||||
}
|
||||
|
||||
var pbpHdr = Utils.AsRef<PbpHeader>(hdr);
|
||||
var pbpHdr = MemoryMarshal.AsRef<PbpHeader>(hdr);
|
||||
if (pbpHdr.Sig != 0x50425000)
|
||||
{
|
||||
Console.WriteLine("Wrong pbp sig");
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace PspCrypto
|
|||
static int Kirk4(Span<byte> buf, int size, int type)
|
||||
{
|
||||
int retv;
|
||||
ref var hdr = ref Utils.AsRef<KIRKEngine.KIRK_AES128CBC_HEADER>(buf);
|
||||
ref var hdr = ref MemoryMarshal.AsRef<KIRKEngine.KIRK_AES128CBC_HEADER>(buf);
|
||||
hdr.mode = KIRKEngine.KIRK_MODE_ENCRYPT_CBC;
|
||||
hdr.keyseed = type;
|
||||
hdr.data_size = size;
|
||||
|
@ -83,7 +83,7 @@ namespace PspCrypto
|
|||
static int Kirk5(Span<byte> buf, int size)
|
||||
{
|
||||
int retv;
|
||||
ref var hdr = ref Utils.AsRef<KIRKEngine.KIRK_AES128CBC_HEADER>(buf);
|
||||
ref var hdr = ref MemoryMarshal.AsRef<KIRKEngine.KIRK_AES128CBC_HEADER>(buf);
|
||||
hdr.mode = KIRKEngine.KIRK_MODE_ENCRYPT_CBC;
|
||||
hdr.keyseed = 0x0100;
|
||||
hdr.data_size = size;
|
||||
|
@ -99,7 +99,7 @@ namespace PspCrypto
|
|||
static int Kirk7(Span<byte> buf, int size, int type)
|
||||
{
|
||||
int retv;
|
||||
ref var hdr = ref Utils.AsRef<KIRKEngine.KIRK_AES128CBC_HEADER>(buf);
|
||||
ref var hdr = ref MemoryMarshal.AsRef<KIRKEngine.KIRK_AES128CBC_HEADER>(buf);
|
||||
hdr.mode = KIRKEngine.KIRK_MODE_DECRYPT_CBC;
|
||||
hdr.keyseed = type;
|
||||
hdr.data_size = size;
|
||||
|
@ -115,7 +115,7 @@ namespace PspCrypto
|
|||
static int Kirk8(Span<byte> buf, int size)
|
||||
{
|
||||
int retv;
|
||||
ref var hdr = ref Utils.AsRef<KIRKEngine.KIRK_AES128CBC_HEADER>(buf);
|
||||
ref var hdr = ref MemoryMarshal.AsRef<KIRKEngine.KIRK_AES128CBC_HEADER>(buf);
|
||||
hdr.mode = KIRKEngine.KIRK_MODE_DECRYPT_CBC;
|
||||
hdr.keyseed = 0x0100;
|
||||
hdr.data_size = size;
|
||||
|
@ -553,7 +553,7 @@ namespace PspCrypto
|
|||
|
||||
public static int sceDrmBBMacFinal2(Span<byte> mkey, ReadOnlySpan<byte> hash, ReadOnlySpan<byte> vkey)
|
||||
{
|
||||
int i, retv, type;
|
||||
int retv, type;
|
||||
byte[] tmp = new byte[16];
|
||||
int kbuf;
|
||||
ref MAC_KEY macKey = ref MemoryMarshal.AsRef<MAC_KEY>(mkey);
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace PspCrypto
|
|||
|
||||
data[..dataSize].CopyTo(pgdData[dataOffset..]);
|
||||
|
||||
ref var pgdHdr = ref Utils.AsRef<PgdHeader>(pgdData);
|
||||
ref var pgdHdr = ref MemoryMarshal.AsRef<PgdHeader>(pgdData);
|
||||
pgdHdr.Magic = 0x44475000;
|
||||
pgdHdr.KeyIndex = keyIndex;
|
||||
pgdHdr.DrmType = drmType;
|
||||
|
@ -81,7 +81,7 @@ namespace PspCrypto
|
|||
}
|
||||
|
||||
// Set the decryption parameters in the decrypted header.
|
||||
ref var pgdDesc = ref Utils.AsRef<PgdDesc>(pgdHdr.PgdDesc);
|
||||
ref var pgdDesc = ref MemoryMarshal.AsRef<PgdDesc>(pgdHdr.PgdDesc);
|
||||
pgdDesc.DataSize = dataSize;
|
||||
pgdDesc.BlockSize = blockSize;
|
||||
pgdDesc.DataOffset = dataOffset;
|
||||
|
|
|
@ -169,7 +169,7 @@ namespace PspCrypto
|
|||
{
|
||||
throw new ArgumentException("stream too small", nameof(stream));
|
||||
}
|
||||
var header = Utils.AsRef<PgdHeader>(hdr);
|
||||
var header = MemoryMarshal.AsRef<PgdHeader>(hdr);
|
||||
_keyIndex = header.KeyIndex;
|
||||
if (_keyIndex == 1)
|
||||
{
|
||||
|
@ -234,7 +234,7 @@ namespace PspCrypto
|
|||
throw new IOException("Wrong MAC 0x80");
|
||||
}
|
||||
|
||||
if (!Utils.isEmpty(_versionKey, 0x10))
|
||||
if (!Utils.IsEmpty(_versionKey, 0x10))
|
||||
{
|
||||
ret = CheckBBMac(hdr, 0x70, _versionKey, header.Hash70, macType);
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ namespace PspCrypto
|
|||
{
|
||||
throw new IOException($"Error 0x{ret:X8}");
|
||||
}
|
||||
var desc = Utils.AsRef<PgdDesc>(header.PgdDesc);
|
||||
var desc = MemoryMarshal.AsRef<PgdDesc>(header.PgdDesc);
|
||||
if (desc.Version != 0)
|
||||
{
|
||||
throw new IOException($"Error 0x{8051020:X8}");
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using PspCrypto.Security.Cryptography;
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using PspCrypto.Security.Cryptography;
|
||||
|
||||
namespace PspCrypto
|
||||
{
|
||||
|
@ -68,17 +65,6 @@ namespace PspCrypto
|
|||
return new ECDsaManaged(par, ebootPbp, type);
|
||||
}
|
||||
|
||||
public static ECDsa CreateNet(ECCurve curve, byte[] privateKey, byte[] pubx, byte[] puby)
|
||||
{
|
||||
var par = new ECParameters
|
||||
{
|
||||
Curve = curve,
|
||||
D = privateKey,
|
||||
Q = { X = pubx, Y = puby }
|
||||
};
|
||||
return ECDsa.Create(par);
|
||||
}
|
||||
|
||||
public static void SignNpImageHeader(Span<byte> npHdr)
|
||||
{
|
||||
var curve = SetCurve(KeyVault.ec_p, KeyVault.ec_a, KeyVault.ec_b2, KeyVault.ec_N2, KeyVault.Gx2,
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using ECDsaTest.SafeHandles;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
internal static partial class Crypto
|
||||
{
|
||||
|
||||
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_BigNumDestroy")]
|
||||
internal static extern void BigNumDestroy(IntPtr a);
|
||||
|
||||
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_BigNumToBinary")]
|
||||
private static extern unsafe int BigNumToBinary(SafeBignumHandle a, byte* to);
|
||||
|
||||
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_GetBigNumBytes")]
|
||||
private static extern int GetBigNumBytes(SafeBignumHandle a);
|
||||
|
||||
|
||||
internal static byte[] ExtractBignum(IntPtr bignum, int targetSize)
|
||||
{
|
||||
// Given that the only reference held to bignum is an IntPtr, create an unowned SafeHandle
|
||||
// to ensure that we don't destroy the key after extraction.
|
||||
using (SafeBignumHandle handle = new SafeBignumHandle(bignum, ownsHandle: false))
|
||||
{
|
||||
return ExtractBignum(handle, targetSize);
|
||||
}
|
||||
}
|
||||
|
||||
private static unsafe byte[] ExtractBignum(SafeBignumHandle bignum, int targetSize)
|
||||
{
|
||||
if (bignum == null || bignum.IsInvalid)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int compactSize = GetBigNumBytes(bignum);
|
||||
|
||||
if (targetSize < compactSize)
|
||||
{
|
||||
targetSize = compactSize;
|
||||
}
|
||||
|
||||
// OpenSSL BIGNUM values do not record leading zeroes.
|
||||
// Windows Crypt32 does.
|
||||
//
|
||||
// Since RSACryptoServiceProvider already checks that RSAParameters.DP.Length is
|
||||
// exactly half of RSAParameters.Modulus.Length, we need to left-pad (big-endian)
|
||||
// the array with zeroes.
|
||||
int offset = targetSize - compactSize;
|
||||
|
||||
byte[] buf = new byte[targetSize];
|
||||
|
||||
fixed (byte* to = buf)
|
||||
{
|
||||
byte* start = to + offset;
|
||||
BigNumToBinary(bignum, start);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
internal static partial class Crypto
|
||||
{
|
||||
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_ErrClearError")]
|
||||
internal static extern ulong ErrClearError();
|
||||
|
||||
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_ErrGetErrorAlloc")]
|
||||
private static extern ulong ErrGetErrorAlloc([MarshalAs(UnmanagedType.Bool)] out bool isAllocFailure);
|
||||
|
||||
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_ErrErrorStringN")]
|
||||
private static extern unsafe void ErrErrorStringN(ulong e, byte* buf, int len);
|
||||
|
||||
private static unsafe string ErrErrorStringN(ulong error)
|
||||
{
|
||||
var buffer = new byte[1024];
|
||||
fixed (byte* buf = &buffer[0])
|
||||
{
|
||||
ErrErrorStringN(error, buf, buffer.Length);
|
||||
return Marshal.PtrToStringAnsi((IntPtr)buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal static Exception CreateOpenSslCryptographicException()
|
||||
{
|
||||
// The Windows cryptography library reports error codes through
|
||||
// Marshal.GetLastWin32Error, which has a single value when the
|
||||
// function exits, last writer wins.
|
||||
//
|
||||
// OpenSSL maintains an error queue. Calls to ERR_get_error read
|
||||
// values out of the queue in the order that ERR_set_error wrote
|
||||
// them. Nothing enforces that a single call into an OpenSSL
|
||||
// function will guarantee at-most one error being set.
|
||||
//
|
||||
// In order to maintain parity in how error flows look between the
|
||||
// Windows code and the OpenSSL-calling code, drain the queue
|
||||
// whenever an Exception is desired, and report the exception
|
||||
// related to the last value in the queue.
|
||||
bool isAllocFailure;
|
||||
ulong error = ErrGetErrorAlloc(out isAllocFailure);
|
||||
ulong lastRead = error;
|
||||
bool lastIsAllocFailure = isAllocFailure;
|
||||
|
||||
// 0 (there's no named constant) is only returned when the calls
|
||||
// to ERR_get_error exceed the calls to ERR_set_error.
|
||||
while (lastRead != 0)
|
||||
{
|
||||
error = lastRead;
|
||||
isAllocFailure = lastIsAllocFailure;
|
||||
|
||||
lastRead = ErrGetErrorAlloc(out lastIsAllocFailure);
|
||||
}
|
||||
|
||||
// If we're in an error flow which results in an Exception, but
|
||||
// no calls to ERR_set_error were made, throw the unadorned
|
||||
// CryptographicException.
|
||||
if (error == 0)
|
||||
{
|
||||
return new CryptographicException();
|
||||
}
|
||||
|
||||
if (isAllocFailure)
|
||||
{
|
||||
return new OutOfMemoryException();
|
||||
}
|
||||
|
||||
// Even though ErrGetError returns ulong (C++ unsigned long), we
|
||||
// really only expect error codes in the UInt32 range
|
||||
Debug.Assert(error <= uint.MaxValue, "ErrGetError should only return error codes in the UInt32 range.");
|
||||
|
||||
// If there was an error code, and it wasn't something handled specially,
|
||||
// use the OpenSSL error string as the message to a CryptographicException.
|
||||
return new OpenSslCryptographicException(unchecked((int)error), ErrErrorStringN(error));
|
||||
}
|
||||
|
||||
private sealed class OpenSslCryptographicException : CryptographicException
|
||||
{
|
||||
internal OpenSslCryptographicException(int errorCode, string message)
|
||||
: base(message)
|
||||
{
|
||||
HResult = errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using ECDsaTest.SafeHandles;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
internal static partial class Crypto
|
||||
{
|
||||
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EcKeyCreateByExplicitParameters")]
|
||||
internal static extern SafeEcKeyHandle EcKeyCreateByExplicitParameters(
|
||||
ECCurve.ECCurveType curveType,
|
||||
byte[] qx, int qxLength,
|
||||
byte[] qy, int qyLength,
|
||||
byte[] d, int dLength,
|
||||
byte[] p, int pLength,
|
||||
byte[] a, int aLength,
|
||||
byte[] b, int bLength,
|
||||
byte[] gx, int gxLength,
|
||||
byte[] gy, int gyLength,
|
||||
byte[] order, int nLength,
|
||||
byte[] cofactor, int cofactorLength,
|
||||
byte[] seed, int seedLength);
|
||||
|
||||
internal static SafeEcKeyHandle EcKeyCreateByExplicitCurve(ECCurve curve)
|
||||
{
|
||||
byte[] p;
|
||||
if (curve.IsPrime)
|
||||
{
|
||||
p = curve.Prime;
|
||||
}
|
||||
else if (curve.IsCharacteristic2)
|
||||
{
|
||||
p = curve.Polynomial;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new PlatformNotSupportedException(string.Format("The specified curve '{0}' or its parameters are not valid for this platform.", curve.CurveType.ToString()));
|
||||
}
|
||||
|
||||
SafeEcKeyHandle key = Interop.Crypto.EcKeyCreateByExplicitParameters(
|
||||
curve.CurveType,
|
||||
null, 0,
|
||||
null, 0,
|
||||
null, 0,
|
||||
p, p.Length,
|
||||
curve.A, curve.A.Length,
|
||||
curve.B, curve.B.Length,
|
||||
curve.G.X, curve.G.X.Length,
|
||||
curve.G.Y, curve.G.Y.Length,
|
||||
curve.Order, curve.Order.Length,
|
||||
curve.Cofactor, curve.Cofactor.Length,
|
||||
curve.Seed, curve.Seed == null ? 0 : curve.Seed.Length);
|
||||
|
||||
if (key == null || key.IsInvalid)
|
||||
{
|
||||
if (key != null)
|
||||
key.Dispose();
|
||||
throw Interop.Crypto.CreateOpenSslCryptographicException();
|
||||
}
|
||||
|
||||
// EcKeyCreateByExplicitParameters may have polluted the error queue, but key was good in the end.
|
||||
// Clean up the error queue.
|
||||
Interop.Crypto.ErrClearError();
|
||||
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using ECDsaTest;
|
||||
using ECDsaTest.SafeHandles;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
internal static partial class Crypto
|
||||
{
|
||||
internal static bool EcDsaSignEx(ReadOnlySpan<byte> dgst, Span<byte> sig, [In, Out] ref int siglen,
|
||||
ReadOnlySpan<byte> kinv, ReadOnlySpan<byte> rp, SafeEcKeyHandle ecKey) => EcDsaSignEx(
|
||||
ref MemoryMarshal.GetReference(dgst), dgst.Length, ref MemoryMarshal.GetReference(sig), ref siglen,
|
||||
ref MemoryMarshal.GetReference(kinv), kinv.Length, ref MemoryMarshal.GetReference(rp), rp.Length, ecKey);
|
||||
|
||||
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EcDsaSignEx")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool EcDsaSignEx(ref byte dgst, int dlen, ref byte sig, [In, Out] ref int siglen,
|
||||
ref byte kinv, int kinvlen, ref byte rp, int rplen, SafeEcKeyHandle ecKey);
|
||||
|
||||
// returns the maximum length of a DER encoded ECDSA signature created with this key.
|
||||
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EcDsaSize")]
|
||||
private static extern int CryptoNative_EcDsaSize(SafeEcKeyHandle ecKey);
|
||||
|
||||
internal static int EcDsaSize(SafeEcKeyHandle ecKey)
|
||||
{
|
||||
int ret = CryptoNative_EcDsaSize(ecKey);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
throw CreateOpenSslCryptographicException();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
internal static PspParameter EcPspParameter(SafeEcKeyHandle key, ReadOnlySpan<byte> sha256, int len)
|
||||
{
|
||||
SafeBignumHandle kinv_bn, rp_bn;
|
||||
int kinvlen, rplen;
|
||||
|
||||
bool refAdded = false;
|
||||
try
|
||||
{
|
||||
key.DangerousAddRef(ref refAdded);
|
||||
var ret = EcPspParameter(key, ref MemoryMarshal.GetReference(sha256), len, out kinv_bn, out kinvlen,
|
||||
out rp_bn, out rplen);
|
||||
if (!ret)
|
||||
{
|
||||
throw Interop.Crypto.CreateOpenSslCryptographicException();
|
||||
}
|
||||
|
||||
using (kinv_bn)
|
||||
using (rp_bn)
|
||||
{
|
||||
var par = new PspParameter
|
||||
{
|
||||
Kinv = Crypto.ExtractBignum(kinv_bn, kinvlen),
|
||||
Rp = Crypto.ExtractBignum(rp_bn, rplen)
|
||||
};
|
||||
return par;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (refAdded)
|
||||
key.DangerousRelease();
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EcPspParameter")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool EcPspParameter(SafeEcKeyHandle ecKey, ref byte sha256, int len, out SafeBignumHandle kinv,
|
||||
out int kinvlen, out SafeBignumHandle rp, out int rplen);
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
internal static partial class Crypto
|
||||
{
|
||||
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EcKeyDestroy")]
|
||||
internal static extern void EcKeyDestroy(IntPtr a);
|
||||
|
||||
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EcKeyUpRef")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool EcKeyUpRef(IntPtr r);
|
||||
}
|
||||
}
|
|
@ -762,7 +762,7 @@ namespace PspCrypto
|
|||
|
||||
static int kirk_CMD0(Span<byte> outbuff, ReadOnlySpan<byte> inbuff, int size, bool generate_trash)
|
||||
{
|
||||
KIRK_CMD1_HEADER header = Utils.AsRef<KIRK_CMD1_HEADER>(outbuff);
|
||||
KIRK_CMD1_HEADER header = MemoryMarshal.AsRef<KIRK_CMD1_HEADER>(outbuff);
|
||||
// header_keys keys = Utils.AsRef<header_keys>(outbuff);
|
||||
int chk_size;
|
||||
Aes k1;
|
||||
|
@ -817,7 +817,7 @@ namespace PspCrypto
|
|||
|
||||
static int kirk_CMD1(Span<byte> outbuff, ReadOnlySpan<byte> inbuff, int size)
|
||||
{
|
||||
KIRK_CMD1_HEADER header = Utils.AsRef<KIRK_CMD1_HEADER>(inbuff);
|
||||
KIRK_CMD1_HEADER header = MemoryMarshal.AsRef<KIRK_CMD1_HEADER>(inbuff);
|
||||
// header_keys keys; //0-15 AES key, 16-31 CMAC key
|
||||
Aes k1;
|
||||
|
||||
|
@ -831,7 +831,7 @@ namespace PspCrypto
|
|||
|
||||
if (header.ecdsa_hash == 1)
|
||||
{
|
||||
KIRK_CMD1_ECDSA_HEADER eheader = Utils.AsRef<KIRK_CMD1_ECDSA_HEADER>(inbuff);
|
||||
KIRK_CMD1_ECDSA_HEADER eheader = MemoryMarshal.AsRef<KIRK_CMD1_ECDSA_HEADER>(inbuff);
|
||||
var curve = ECDsaHelper.SetCurve(KeyVault.ec_p, KeyVault.ec_a, KeyVault.ec_b1, KeyVault.ec_N1, KeyVault.Gx1,
|
||||
KeyVault.Gy1);
|
||||
unsafe
|
||||
|
@ -867,7 +867,7 @@ namespace PspCrypto
|
|||
|
||||
static int kirk_CMD4(Span<byte> outbuff, ReadOnlySpan<byte> inbuff, int size)
|
||||
{
|
||||
KIRK_AES128CBC_HEADER header = Utils.AsRef<KIRK_AES128CBC_HEADER>(inbuff);
|
||||
KIRK_AES128CBC_HEADER header = MemoryMarshal.AsRef<KIRK_AES128CBC_HEADER>(inbuff);
|
||||
byte[] key;
|
||||
Aes aes;
|
||||
|
||||
|
@ -892,7 +892,7 @@ namespace PspCrypto
|
|||
|
||||
static int kirk_CMD7(Span<byte> outbuff, ReadOnlySpan<byte> inbuff, int size)
|
||||
{
|
||||
KIRK_AES128CBC_HEADER header = Utils.AsRef<KIRK_AES128CBC_HEADER>(inbuff);
|
||||
KIRK_AES128CBC_HEADER header = MemoryMarshal.AsRef<KIRK_AES128CBC_HEADER>(inbuff);
|
||||
byte[] key;
|
||||
Aes aes;
|
||||
|
||||
|
@ -915,7 +915,7 @@ namespace PspCrypto
|
|||
|
||||
static int kirk_CMD10(ReadOnlySpan<byte> inbuff, int insize)
|
||||
{
|
||||
KIRK_CMD1_HEADER header = Utils.AsRef<KIRK_CMD1_HEADER>(inbuff);
|
||||
KIRK_CMD1_HEADER header = MemoryMarshal.AsRef<KIRK_CMD1_HEADER>(inbuff);
|
||||
// header_keys keys; //0-15 AES key, 16-31 CMAC key
|
||||
Span<byte> cmac_header_hash = stackalloc byte[16];
|
||||
Span<byte> cmac_data_hash = stackalloc byte[16];
|
||||
|
@ -951,7 +951,7 @@ namespace PspCrypto
|
|||
|
||||
static int kirk_CMD11(Span<byte> outbuff, ReadOnlySpan<byte> inbuff, int size)
|
||||
{
|
||||
KIRK_SHA1_HEADER header = Utils.AsRef<KIRK_SHA1_HEADER>(inbuff);
|
||||
KIRK_SHA1_HEADER header = MemoryMarshal.AsRef<KIRK_SHA1_HEADER>(inbuff);
|
||||
if (!is_kirk_initialized) return KIRK_NOT_INITIALIZED;
|
||||
if (header.data_size == 0 || size == 0) return KIRK_DATA_SIZE_ZERO;
|
||||
|
||||
|
@ -1044,7 +1044,7 @@ namespace PspCrypto
|
|||
static int kirk_CMD16(Span<byte> outbuff, int outsize, ReadOnlySpan<byte> inbuff, int insize)
|
||||
{
|
||||
byte[] dec_private = new byte[0x20];
|
||||
KIRK_CMD16_BUFFER signbuf = Utils.AsRef<KIRK_CMD16_BUFFER>(inbuff);
|
||||
KIRK_CMD16_BUFFER signbuf = MemoryMarshal.AsRef<KIRK_CMD16_BUFFER>(inbuff);
|
||||
//ECDSA_SIG sig = BufferToStruct<ECDSA_SIG>(outbuff);
|
||||
|
||||
if (insize != 0x34) return KIRK_INVALID_SIZE;
|
||||
|
@ -1071,7 +1071,7 @@ namespace PspCrypto
|
|||
|
||||
static int kirk_CMD17(ReadOnlySpan<byte> inbuff, int insize)
|
||||
{
|
||||
KIRK_CMD17_BUFFER sig = Utils.AsRef<KIRK_CMD17_BUFFER>(inbuff);
|
||||
KIRK_CMD17_BUFFER sig = MemoryMarshal.AsRef<KIRK_CMD17_BUFFER>(inbuff);
|
||||
|
||||
if (insize != 0x64) return KIRK_INVALID_SIZE;
|
||||
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
using System;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace PspCrypto
|
||||
{
|
||||
public class RijndaelMod : Aes
|
||||
{
|
||||
public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV)
|
||||
{
|
||||
return CreateTransform(rgbKey, encrypting: false);
|
||||
}
|
||||
|
||||
public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)
|
||||
{
|
||||
return CreateTransform(rgbKey, encrypting: true);
|
||||
}
|
||||
|
||||
public override void GenerateIV()
|
||||
{
|
||||
}
|
||||
|
||||
public override void GenerateKey()
|
||||
{
|
||||
byte[] key = new byte[KeySize / BitsPerByte];
|
||||
RandomNumberGenerator.Fill(key);
|
||||
Key = key;
|
||||
}
|
||||
|
||||
private ICryptoTransform CreateTransform(byte[] rgbKey, bool encrypting)
|
||||
{
|
||||
if (rgbKey == null)
|
||||
throw new ArgumentNullException(nameof(rgbKey));
|
||||
return new RijndaelModTransform(rgbKey, BlockSizeValue, encrypting);
|
||||
}
|
||||
|
||||
private const int BitsPerByte = 8;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,272 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using PspCrypto.Security.Cryptography;
|
||||
|
||||
namespace PspCrypto
|
||||
{
|
||||
public class SHA224Managed_OLD : SHA224
|
||||
{
|
||||
|
||||
private const int BLOCK_SIZE_BYTES = 64;
|
||||
|
||||
private uint[] _H;
|
||||
private ulong count;
|
||||
private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth.
|
||||
private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.
|
||||
private uint[] buff;
|
||||
|
||||
public SHA224Managed_OLD()
|
||||
{
|
||||
_H = new uint[8];
|
||||
_ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];
|
||||
buff = new uint[64];
|
||||
Initialize();
|
||||
}
|
||||
|
||||
private uint Ch(uint u, uint v, uint w)
|
||||
{
|
||||
return (u & v) ^ (~u & w);
|
||||
}
|
||||
|
||||
private uint Maj(uint u, uint v, uint w)
|
||||
{
|
||||
return (u & v) ^ (u & w) ^ (v & w);
|
||||
}
|
||||
|
||||
private uint Ro0(uint x)
|
||||
{
|
||||
return ((x >> 7) | (x << 25))
|
||||
^ ((x >> 18) | (x << 14))
|
||||
^ (x >> 3);
|
||||
}
|
||||
|
||||
private uint Ro1(uint x)
|
||||
{
|
||||
return ((x >> 17) | (x << 15))
|
||||
^ ((x >> 19) | (x << 13))
|
||||
^ (x >> 10);
|
||||
}
|
||||
|
||||
private uint Sig0(uint x)
|
||||
{
|
||||
return ((x >> 2) | (x << 30))
|
||||
^ ((x >> 13) | (x << 19))
|
||||
^ ((x >> 22) | (x << 10));
|
||||
}
|
||||
|
||||
private uint Sig1(uint x)
|
||||
{
|
||||
return ((x >> 6) | (x << 26))
|
||||
^ ((x >> 11) | (x << 21))
|
||||
^ ((x >> 25) | (x << 7));
|
||||
}
|
||||
|
||||
|
||||
public void HashData2(ReadOnlySpan<byte> data, Span<byte> hash)
|
||||
{
|
||||
var tmp = ComputeHash(data.ToArray());
|
||||
tmp.CopyTo(hash);
|
||||
}
|
||||
|
||||
protected override void HashCore(byte[] rgb, int start, int size)
|
||||
{
|
||||
int i;
|
||||
State = 1;
|
||||
|
||||
if (_ProcessingBufferCount != 0)
|
||||
{
|
||||
if (size < (BLOCK_SIZE_BYTES - _ProcessingBufferCount))
|
||||
{
|
||||
System.Buffer.BlockCopy(rgb, start, _ProcessingBuffer, _ProcessingBufferCount, size);
|
||||
_ProcessingBufferCount += size;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount);
|
||||
System.Buffer.BlockCopy(rgb, start, _ProcessingBuffer, _ProcessingBufferCount, i);
|
||||
ProcessBlock(_ProcessingBuffer, 0);
|
||||
_ProcessingBufferCount = 0;
|
||||
start += i;
|
||||
size -= i;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < size - size % BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES)
|
||||
{
|
||||
ProcessBlock(rgb, start + i);
|
||||
}
|
||||
|
||||
if (size % BLOCK_SIZE_BYTES != 0)
|
||||
{
|
||||
System.Buffer.BlockCopy(rgb, size - size % BLOCK_SIZE_BYTES + start, _ProcessingBuffer, 0, size % BLOCK_SIZE_BYTES);
|
||||
_ProcessingBufferCount = size % BLOCK_SIZE_BYTES;
|
||||
}
|
||||
}
|
||||
|
||||
protected override byte[] HashFinal()
|
||||
{
|
||||
byte[] hash = new byte[28];
|
||||
int i, j;
|
||||
|
||||
ProcessFinalBlock(_ProcessingBuffer, 0, _ProcessingBufferCount);
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
hash[i * 4 + j] = (byte)(_H[i] >> (24 - j * 8));
|
||||
}
|
||||
}
|
||||
|
||||
State = 0;
|
||||
return hash;
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
count = 0;
|
||||
_ProcessingBufferCount = 0;
|
||||
|
||||
_H[0] = 0xC1059ED8;
|
||||
_H[1] = 0x367CD507;
|
||||
_H[2] = 0x3070DD17;
|
||||
_H[3] = 0xF70E5939;
|
||||
_H[4] = 0xFFC00B31;
|
||||
_H[5] = 0x68581511;
|
||||
_H[6] = 0x64F98FA7;
|
||||
_H[7] = 0xBEFA4FA4;
|
||||
}
|
||||
|
||||
private void ProcessBlock(byte[] inputBuffer, int inputOffset)
|
||||
{
|
||||
uint a, b, c, d, e, f, g, h;
|
||||
uint t1, t2;
|
||||
int i;
|
||||
uint[] K1 = _K1;
|
||||
uint[] buff = this.buff;
|
||||
|
||||
count += BLOCK_SIZE_BYTES;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
buff[i] = (uint)(((inputBuffer[inputOffset + 4 * i]) << 24)
|
||||
| ((inputBuffer[inputOffset + 4 * i + 1]) << 16)
|
||||
| ((inputBuffer[inputOffset + 4 * i + 2]) << 8)
|
||||
| ((inputBuffer[inputOffset + 4 * i + 3])));
|
||||
}
|
||||
|
||||
|
||||
for (i = 16; i < 64; i++)
|
||||
{
|
||||
t1 = buff[i - 15];
|
||||
t1 = (((t1 >> 7) | (t1 << 25)) ^ ((t1 >> 18) | (t1 << 14)) ^ (t1 >> 3));
|
||||
|
||||
t2 = buff[i - 2];
|
||||
t2 = (((t2 >> 17) | (t2 << 15)) ^ ((t2 >> 19) | (t2 << 13)) ^ (t2 >> 10));
|
||||
buff[i] = t2 + buff[i - 7] + t1 + buff[i - 16];
|
||||
}
|
||||
|
||||
a = _H[0];
|
||||
b = _H[1];
|
||||
c = _H[2];
|
||||
d = _H[3];
|
||||
e = _H[4];
|
||||
f = _H[5];
|
||||
g = _H[6];
|
||||
h = _H[7];
|
||||
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
t1 = h + (((e >> 6) | (e << 26)) ^ ((e >> 11) | (e << 21)) ^ ((e >> 25) | (e << 7))) + ((e & f) ^ (~e & g)) + K1[i] + buff[i];
|
||||
|
||||
t2 = (((a >> 2) | (a << 30)) ^ ((a >> 13) | (a << 19)) ^ ((a >> 22) | (a << 10)));
|
||||
t2 = t2 + ((a & b) ^ (a & c) ^ (b & c));
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
}
|
||||
|
||||
_H[0] += a;
|
||||
_H[1] += b;
|
||||
_H[2] += c;
|
||||
_H[3] += d;
|
||||
_H[4] += e;
|
||||
_H[5] += f;
|
||||
_H[6] += g;
|
||||
_H[7] += h;
|
||||
}
|
||||
|
||||
private void ProcessFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
|
||||
{
|
||||
ulong total = count + (ulong)inputCount;
|
||||
int paddingSize = (56 - (int)(total % BLOCK_SIZE_BYTES));
|
||||
|
||||
if (paddingSize < 1)
|
||||
paddingSize += BLOCK_SIZE_BYTES;
|
||||
|
||||
byte[] fooBuffer = new byte[inputCount + paddingSize + 8];
|
||||
|
||||
for (int i = 0; i < inputCount; i++)
|
||||
{
|
||||
fooBuffer[i] = inputBuffer[i + inputOffset];
|
||||
}
|
||||
|
||||
fooBuffer[inputCount] = 0x80;
|
||||
for (int i = inputCount + 1; i < inputCount + paddingSize; i++)
|
||||
{
|
||||
fooBuffer[i] = 0x00;
|
||||
}
|
||||
|
||||
// I deal in bytes. The algorithm deals in bits.
|
||||
ulong size = total << 3;
|
||||
AddLength(size, fooBuffer, inputCount + paddingSize);
|
||||
ProcessBlock(fooBuffer, 0);
|
||||
|
||||
if (inputCount + paddingSize + 8 == 128)
|
||||
{
|
||||
ProcessBlock(fooBuffer, 64);
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddLength(ulong length, byte[] buffer, int position)
|
||||
{
|
||||
buffer[position++] = (byte)(length >> 56);
|
||||
buffer[position++] = (byte)(length >> 48);
|
||||
buffer[position++] = (byte)(length >> 40);
|
||||
buffer[position++] = (byte)(length >> 32);
|
||||
buffer[position++] = (byte)(length >> 24);
|
||||
buffer[position++] = (byte)(length >> 16);
|
||||
buffer[position++] = (byte)(length >> 8);
|
||||
buffer[position] = (byte)(length);
|
||||
}
|
||||
|
||||
// SHA-224/256 Constants
|
||||
// Represent the first 32 bits of the fractional parts of the
|
||||
// cube roots of the first sixty-four prime numbers
|
||||
public readonly static uint[] _K1 = {
|
||||
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
|
||||
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
|
||||
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
|
||||
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
|
||||
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
|
||||
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
|
||||
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
|
||||
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
|
||||
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
|
||||
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
|
||||
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
|
||||
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
|
||||
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
|
||||
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
|
||||
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
|
||||
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace ECDsaTest.SafeHandles
|
||||
{
|
||||
internal sealed class SafeBignumHandle : SafeHandle
|
||||
{
|
||||
private SafeBignumHandle() :
|
||||
base(IntPtr.Zero, ownsHandle: true)
|
||||
{
|
||||
}
|
||||
|
||||
internal SafeBignumHandle(IntPtr handle, bool ownsHandle)
|
||||
: base(handle, ownsHandle)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
Interop.Crypto.BigNumDestroy(handle);
|
||||
SetHandle(IntPtr.Zero);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool IsInvalid
|
||||
{
|
||||
get { return handle == IntPtr.Zero; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace ECDsaTest.SafeHandles
|
||||
{
|
||||
internal sealed class SafeEcKeyHandle : SafeHandle
|
||||
{
|
||||
private SafeEcKeyHandle() :
|
||||
base(IntPtr.Zero, ownsHandle: true)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
Interop.Crypto.EcKeyDestroy(handle);
|
||||
SetHandle(IntPtr.Zero);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool IsInvalid
|
||||
{
|
||||
get { return handle == IntPtr.Zero; }
|
||||
}
|
||||
|
||||
internal static SafeEcKeyHandle DuplicateHandle(IntPtr handle)
|
||||
{
|
||||
Debug.Assert(handle != IntPtr.Zero);
|
||||
|
||||
// Reliability: Allocate the SafeHandle before calling EC_KEY_up_ref so
|
||||
// that we don't lose a tracked reference in low-memory situations.
|
||||
SafeEcKeyHandle safeHandle = new SafeEcKeyHandle();
|
||||
|
||||
if (!Interop.Crypto.EcKeyUpRef(handle))
|
||||
{
|
||||
throw Interop.Crypto.CreateOpenSslCryptographicException();
|
||||
}
|
||||
|
||||
safeHandle.SetHandle(handle);
|
||||
return safeHandle;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -438,7 +438,7 @@ namespace PspCrypto
|
|||
static int Kirk8(Span<byte> buf, int size, int use_polling)
|
||||
{
|
||||
int retv;
|
||||
ref var hdr = ref Utils.AsRef<KIRKEngine.KIRK_AES128CBC_HEADER>(buf);
|
||||
ref var hdr = ref MemoryMarshal.AsRef<KIRKEngine.KIRK_AES128CBC_HEADER>(buf);
|
||||
hdr.mode = KIRKEngine.KIRK_MODE_DECRYPT_CBC;
|
||||
hdr.keyseed = 0x0100;
|
||||
hdr.data_size = size;
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
using System;
|
||||
using PspCrypto.Security.Cryptography;
|
||||
using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using PspCrypto.Security.Cryptography;
|
||||
|
||||
namespace PspCrypto
|
||||
{
|
||||
|
@ -142,7 +140,7 @@ namespace PspCrypto
|
|||
}
|
||||
}
|
||||
|
||||
unsafe struct sceDiscInfo
|
||||
unsafe struct SceDiscInfo
|
||||
{
|
||||
private fixed byte _id[0x30];
|
||||
|
||||
|
@ -757,7 +755,7 @@ namespace PspCrypto
|
|||
Span<byte> pbpHdrDigest = stackalloc byte[32];
|
||||
Span<byte> discsDigest = stackalloc byte[32];
|
||||
Span<byte> ebootSigtmp = stackalloc byte[512];
|
||||
ref var sceEbootPbp = ref Utils.AsRef<SceEbootPbp>(ebootSigtmp);
|
||||
ref var sceEbootPbp = ref MemoryMarshal.AsRef<SceEbootPbp>(ebootSigtmp);
|
||||
if ((blockSize & 0x3F) != 0)
|
||||
{
|
||||
blockSize &= unchecked((int)0xFFFFFFC0);
|
||||
|
@ -775,7 +773,7 @@ namespace PspCrypto
|
|||
ebootSig.Fill(0);
|
||||
sceEbootPbp.SwVer = swVer;
|
||||
sceEbootPbp.Aid = Aid;
|
||||
sceEbootPbp.SecureTick = Utils.AsRef<ulong>(secureTick);
|
||||
sceEbootPbp.SecureTick = MemoryMarshal.AsRef<ulong>(secureTick);
|
||||
|
||||
var sha224 = SHA224.Create();
|
||||
var hash = sha224.ComputeHash(sceDiskInfo[..200].ToArray());
|
||||
|
@ -785,7 +783,7 @@ namespace PspCrypto
|
|||
return ret;
|
||||
}
|
||||
|
||||
var discInfo = Utils.AsRef<sceDiscInfo>(sceDiskInfo);
|
||||
var discInfo = MemoryMarshal.AsRef<SceDiscInfo>(sceDiskInfo);
|
||||
ret = unchecked((int)0x80870005);
|
||||
if (discInfo.DiscCount > 6)
|
||||
{
|
||||
|
@ -854,7 +852,7 @@ namespace PspCrypto
|
|||
return ret;
|
||||
}
|
||||
discInfo.DiscsSig.CopyTo(sceEbootPbp.NpUmdImgSig);
|
||||
var ebootsigDigst = sha224.ComputeHash(ebootSigtmp.Slice(0, 0x1C8).ToArray());
|
||||
var ebootsigDigst = sha224.ComputeHash(ebootSigtmp[..0x1C8].ToArray());
|
||||
ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(ebootsigDigst, sceEbootPbp.Sig, 1);
|
||||
if (ret != 0)
|
||||
{
|
||||
|
@ -874,13 +872,13 @@ namespace PspCrypto
|
|||
var sha224 = SHA224.Create();
|
||||
var ret = unchecked((int)0x80870005);
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
buffer = buffer.Slice(0, blockSize);
|
||||
buffer = buffer[..blockSize];
|
||||
var readSize = stream.Read(buffer);
|
||||
if (readSize < 0x28)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
var pbpHeader = Utils.AsRef<PbpHeader>(buffer);
|
||||
var pbpHeader = MemoryMarshal.AsRef<PbpHeader>(buffer);
|
||||
if (pbpHeader.Sig != 0x50425000)
|
||||
{
|
||||
return ret;
|
||||
|
@ -925,7 +923,7 @@ namespace PspCrypto
|
|||
toRead = blockSize;
|
||||
}
|
||||
|
||||
readSize = stream.Read(buffer.Slice(0, toRead));
|
||||
readSize = stream.Read(buffer[..toRead]);
|
||||
if (readSize == 0)
|
||||
{
|
||||
return -1;
|
||||
|
@ -968,7 +966,7 @@ namespace PspCrypto
|
|||
toRead = blockSize;
|
||||
}
|
||||
|
||||
readSize = stream.Read(buffer.Slice(0, toRead));
|
||||
readSize = stream.Read(buffer[..toRead]);
|
||||
if (readSize == 0)
|
||||
{
|
||||
return -1;
|
||||
|
@ -997,7 +995,7 @@ namespace PspCrypto
|
|||
sha224.Hash.CopyTo(dataDigest);
|
||||
|
||||
stream.Seek(pbpHeader.DataPsarOff, SeekOrigin.Begin);
|
||||
readSize = stream.Read(buffer.Slice(0, 0x100));
|
||||
readSize = stream.Read(buffer[..0x100]);
|
||||
if (readSize == 0x100)
|
||||
{
|
||||
ret = 0;
|
||||
|
@ -1018,7 +1016,8 @@ namespace PspCrypto
|
|||
{
|
||||
return -1;
|
||||
}
|
||||
using(FileStream fstream = fi.OpenRead()){
|
||||
using (FileStream fstream = fi.OpenRead())
|
||||
{
|
||||
return SceNpDrmEbootSigGen(fstream, type, ebootSig, swVer, buffer, blockSize);
|
||||
}
|
||||
|
||||
|
@ -1028,7 +1027,7 @@ namespace PspCrypto
|
|||
Span<byte> pbpHdrDigest = stackalloc byte[32];
|
||||
Span<byte> npUmdImgDigest = stackalloc byte[32];
|
||||
Span<byte> ebootSigtmp = stackalloc byte[512];
|
||||
ref var sceEbootPbp = ref Utils.AsRef<SceEbootPbp>(ebootSigtmp);
|
||||
ref var sceEbootPbp = ref MemoryMarshal.AsRef<SceEbootPbp>(ebootSigtmp);
|
||||
if ((blockSize & 0x3F) != 0)
|
||||
{
|
||||
blockSize &= unchecked((int)0xFFFFFFC0);
|
||||
|
@ -1044,7 +1043,7 @@ namespace PspCrypto
|
|||
ebootSig.Fill(0);
|
||||
sceEbootPbp.SwVer = swVer;
|
||||
sceEbootPbp.Aid = Aid;
|
||||
sceEbootPbp.SecureTick = Utils.AsRef<ulong>(secureTick);
|
||||
sceEbootPbp.SecureTick = MemoryMarshal.AsRef<ulong>(secureTick);
|
||||
|
||||
long flen = ebootStream.Length;
|
||||
int ret = SceEbootPbpDigest(ebootStream, flen, pbpHdrDigest, npUmdImgDigest, buffer, blockSize);
|
||||
|
@ -1056,10 +1055,10 @@ namespace PspCrypto
|
|||
sceEbootPbp.KeyType = 1;
|
||||
sceEbootPbp.PbpSize = flen;
|
||||
sceEbootPbp.Type = type;
|
||||
var psarSig = Encoding.ASCII.GetString(buffer.Slice(0, 8));
|
||||
var psarSig = Encoding.ASCII.GetString(buffer[..8]);
|
||||
if (type == 3)
|
||||
{
|
||||
if (psarSig != "PSISOIMG")
|
||||
if (psarSig != "PSISOIMG" && psarSig != "PSTITLEI")
|
||||
{
|
||||
return -0x7f78fffb;
|
||||
}
|
||||
|
@ -1089,7 +1088,7 @@ namespace PspCrypto
|
|||
}
|
||||
|
||||
var sha224 = SHA224.Create();
|
||||
var ebootsigDigst = sha224.ComputeHash(ebootSigtmp.Slice(0, 0x1C8).ToArray());
|
||||
var ebootsigDigst = sha224.ComputeHash(ebootSigtmp[..0x1C8].ToArray());
|
||||
ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(ebootsigDigst, sceEbootPbp.Sig, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
|
@ -1106,14 +1105,14 @@ namespace PspCrypto
|
|||
var sha224 = SHA224.Create();
|
||||
var ret = unchecked((int)0x80870005);
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
buffer = buffer.Slice(0, blockSize);
|
||||
buffer = buffer[..blockSize];
|
||||
var readSize = stream.Read(buffer);
|
||||
if (readSize < 0x28)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
var pbpHeader = Utils.AsRef<PbpHeader>(buffer);
|
||||
var pbpHeader = MemoryMarshal.AsRef<PbpHeader>(buffer);
|
||||
if (fileSize < pbpHeader.DataPsarOff + 0xFF || pbpHeader.Sig != 0x50425000)
|
||||
{
|
||||
return ret;
|
||||
|
@ -1182,7 +1181,7 @@ namespace PspCrypto
|
|||
sha224.TransformFinalBlock(buffer.ToArray(), 0, 0);
|
||||
sha224.Hash.CopyTo(npUmdImgDigest);
|
||||
stream.Seek(pbpHeader.DataPsarOff, SeekOrigin.Begin);
|
||||
readSize = stream.Read(buffer.Slice(0, 0x100));
|
||||
readSize = stream.Read(buffer[..0x100]);
|
||||
if (readSize == 0x100)
|
||||
{
|
||||
ret = 0;
|
||||
|
@ -1218,7 +1217,7 @@ namespace PspCrypto
|
|||
Span<byte> pbpHdrDigest = stackalloc byte[32];
|
||||
Span<byte> npUmdImgDigest = stackalloc byte[32];
|
||||
Span<byte> ebootSigtmp = stackalloc byte[0x100];
|
||||
ref var sceEbootPbp = ref Utils.AsRef<SceEbootPbp100>(ebootSigtmp);
|
||||
ref var sceEbootPbp = ref MemoryMarshal.AsRef<SceEbootPbp100>(ebootSigtmp);
|
||||
if ((blockSize & 0x3F) != 0)
|
||||
{
|
||||
blockSize &= unchecked((int)0xFFFFFFC0);
|
||||
|
@ -1236,11 +1235,11 @@ namespace PspCrypto
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (Encoding.ASCII.GetString(buffer.Slice(0, 8)) != "NPUMDIMG")
|
||||
if (Encoding.ASCII.GetString(buffer[..8]) != "NPUMDIMG")
|
||||
{
|
||||
return -0x7f78fffb;
|
||||
}
|
||||
buffer.Slice(0, 0x40).CopyTo(ebootSigtmp);
|
||||
buffer[..0x40].CopyTo(ebootSigtmp);
|
||||
sceEbootPbp.Type = 0;
|
||||
sceEbootPbp.Magic = 0x474953444D55504E;
|
||||
|
||||
|
@ -1257,7 +1256,7 @@ namespace PspCrypto
|
|||
}
|
||||
|
||||
var sha224 = SHA224.Create();
|
||||
var ebootsigDigst = sha224.ComputeHash(ebootSigtmp.Slice(0, 0xC8).ToArray());
|
||||
var ebootsigDigst = sha224.ComputeHash(ebootSigtmp[..0xC8].ToArray());
|
||||
ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(ebootsigDigst, sceEbootPbp.Sig, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
|
|
|
@ -1,222 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace System.Formats.Asn1
|
||||
{
|
||||
internal ref struct AsnValueReader
|
||||
{
|
||||
private static readonly byte[] s_singleByte = new byte[1];
|
||||
|
||||
private ReadOnlySpan<byte> _span;
|
||||
private readonly AsnEncodingRules _ruleSet;
|
||||
|
||||
internal AsnValueReader(ReadOnlySpan<byte> span, AsnEncodingRules ruleSet)
|
||||
{
|
||||
_span = span;
|
||||
_ruleSet = ruleSet;
|
||||
}
|
||||
|
||||
internal bool HasData => !_span.IsEmpty;
|
||||
|
||||
internal void ThrowIfNotEmpty()
|
||||
{
|
||||
if (!_span.IsEmpty)
|
||||
{
|
||||
new AsnReader(s_singleByte, _ruleSet).ThrowIfNotEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
internal Asn1Tag PeekTag()
|
||||
{
|
||||
return Asn1Tag.Decode(_span, out _);
|
||||
}
|
||||
|
||||
internal ReadOnlySpan<byte> PeekContentBytes()
|
||||
{
|
||||
AsnDecoder.ReadEncodedValue(
|
||||
_span,
|
||||
_ruleSet,
|
||||
out int contentOffset,
|
||||
out int contentLength,
|
||||
out _);
|
||||
|
||||
return _span.Slice(contentOffset, contentLength);
|
||||
}
|
||||
|
||||
internal ReadOnlySpan<byte> PeekEncodedValue()
|
||||
{
|
||||
AsnDecoder.ReadEncodedValue(_span, _ruleSet, out _, out _, out int consumed);
|
||||
return _span.Slice(0, consumed);
|
||||
}
|
||||
|
||||
internal ReadOnlySpan<byte> ReadEncodedValue()
|
||||
{
|
||||
ReadOnlySpan<byte> value = PeekEncodedValue();
|
||||
_span = _span.Slice(value.Length);
|
||||
return value;
|
||||
}
|
||||
|
||||
internal bool ReadBoolean(Asn1Tag? expectedTag = default)
|
||||
{
|
||||
bool ret = AsnDecoder.ReadBoolean(_span, _ruleSet, out int consumed, expectedTag);
|
||||
_span = _span.Slice(consumed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal BigInteger ReadInteger(Asn1Tag? expectedTag = default)
|
||||
{
|
||||
BigInteger ret = AsnDecoder.ReadInteger(_span, _ruleSet, out int consumed, expectedTag);
|
||||
_span = _span.Slice(consumed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal bool TryReadInt32(out int value, Asn1Tag? expectedTag = default)
|
||||
{
|
||||
bool ret = AsnDecoder.TryReadInt32(_span, _ruleSet, out value, out int consumed, expectedTag);
|
||||
_span = _span.Slice(consumed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal ReadOnlySpan<byte> ReadIntegerBytes(Asn1Tag? expectedTag = default)
|
||||
{
|
||||
ReadOnlySpan<byte> ret = AsnDecoder.ReadIntegerBytes(_span, _ruleSet, out int consumed, expectedTag);
|
||||
_span = _span.Slice(consumed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal bool TryReadPrimitiveBitString(
|
||||
out int unusedBitCount,
|
||||
out ReadOnlySpan<byte> value,
|
||||
Asn1Tag? expectedTag = default)
|
||||
{
|
||||
bool ret = AsnDecoder.TryReadPrimitiveBitString(
|
||||
_span,
|
||||
_ruleSet,
|
||||
out unusedBitCount,
|
||||
out value,
|
||||
out int consumed,
|
||||
expectedTag);
|
||||
|
||||
_span = _span.Slice(consumed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal byte[] ReadBitString(out int unusedBitCount, Asn1Tag? expectedTag = default)
|
||||
{
|
||||
byte[] ret = AsnDecoder.ReadBitString(
|
||||
_span,
|
||||
_ruleSet,
|
||||
out unusedBitCount,
|
||||
out int consumed,
|
||||
expectedTag);
|
||||
|
||||
_span = _span.Slice(consumed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal TFlagsEnum ReadNamedBitListValue<TFlagsEnum>(Asn1Tag? expectedTag = default) where TFlagsEnum : Enum
|
||||
{
|
||||
TFlagsEnum ret = AsnDecoder.ReadNamedBitListValue<TFlagsEnum>(_span, _ruleSet, out int consumed, expectedTag);
|
||||
_span = _span.Slice(consumed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal bool TryReadPrimitiveOctetString(
|
||||
out ReadOnlySpan<byte> value,
|
||||
Asn1Tag? expectedTag = default)
|
||||
{
|
||||
bool ret = AsnDecoder.TryReadPrimitiveOctetString(
|
||||
_span,
|
||||
_ruleSet,
|
||||
out value,
|
||||
out int consumed,
|
||||
expectedTag);
|
||||
|
||||
_span = _span.Slice(consumed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal byte[] ReadOctetString(Asn1Tag? expectedTag = default)
|
||||
{
|
||||
byte[] ret = AsnDecoder.ReadOctetString(
|
||||
_span,
|
||||
_ruleSet,
|
||||
out int consumed,
|
||||
expectedTag);
|
||||
|
||||
_span = _span.Slice(consumed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal string ReadObjectIdentifier(Asn1Tag? expectedTag = default)
|
||||
{
|
||||
string ret = AsnDecoder.ReadObjectIdentifier(_span, _ruleSet, out int consumed, expectedTag);
|
||||
_span = _span.Slice(consumed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal AsnValueReader ReadSequence(Asn1Tag? expectedTag = default)
|
||||
{
|
||||
AsnDecoder.ReadSequence(
|
||||
_span,
|
||||
_ruleSet,
|
||||
out int contentOffset,
|
||||
out int contentLength,
|
||||
out int bytesConsumed,
|
||||
expectedTag);
|
||||
|
||||
ReadOnlySpan<byte> content = _span.Slice(contentOffset, contentLength);
|
||||
_span = _span.Slice(bytesConsumed);
|
||||
return new AsnValueReader(content, _ruleSet);
|
||||
}
|
||||
|
||||
internal AsnValueReader ReadSetOf(Asn1Tag? expectedTag = default, bool skipSortOrderValidation = false)
|
||||
{
|
||||
AsnDecoder.ReadSetOf(
|
||||
_span,
|
||||
_ruleSet,
|
||||
out int contentOffset,
|
||||
out int contentLength,
|
||||
out int bytesConsumed,
|
||||
skipSortOrderValidation: skipSortOrderValidation,
|
||||
expectedTag: expectedTag);
|
||||
|
||||
ReadOnlySpan<byte> content = _span.Slice(contentOffset, contentLength);
|
||||
_span = _span.Slice(bytesConsumed);
|
||||
return new AsnValueReader(content, _ruleSet);
|
||||
}
|
||||
|
||||
internal DateTimeOffset ReadUtcTime(Asn1Tag? expectedTag = default)
|
||||
{
|
||||
DateTimeOffset ret = AsnDecoder.ReadUtcTime(_span, _ruleSet, out int consumed, expectedTag: expectedTag);
|
||||
_span = _span.Slice(consumed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal DateTimeOffset ReadGeneralizedTime(Asn1Tag? expectedTag = default)
|
||||
{
|
||||
DateTimeOffset ret = AsnDecoder.ReadGeneralizedTime(_span, _ruleSet, out int consumed, expectedTag);
|
||||
_span = _span.Slice(consumed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal string ReadCharacterString(UniversalTagNumber encodingType, Asn1Tag? expectedTag = default)
|
||||
{
|
||||
string ret = AsnDecoder.ReadCharacterString(_span, _ruleSet, encodingType, out int consumed, expectedTag);
|
||||
_span = _span.Slice(consumed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal TEnum ReadEnumeratedValue<TEnum>(Asn1Tag? expectedTag = null) where TEnum : Enum
|
||||
{
|
||||
TEnum ret = AsnDecoder.ReadEnumeratedValue<TEnum>(_span, _ruleSet, out int consumed, expectedTag);
|
||||
_span = _span.Slice(consumed);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,137 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Formats.Asn1;
|
||||
|
||||
namespace PspCrypto.Security.Cryptography
|
||||
{
|
||||
//
|
||||
// Common infrastructure for AsymmetricAlgorithm-derived classes that layer on OpenSSL.
|
||||
//
|
||||
internal static partial class AsymmetricAlgorithmHelpers
|
||||
{
|
||||
|
||||
// private static readonly Func<ReadOnlyMemory<byte>, ReadOnlyMemory<byte>[]> ReaderAsn;
|
||||
|
||||
// static AsymmetricAlgorithmHelpers()
|
||||
// {
|
||||
// var assembly = typeof(Aes).Assembly;
|
||||
// var r = assembly.GetType("System.Security.Cryptography.Asn1.AsnReader");
|
||||
// var par1Type = typeof(ReadOnlyMemory<byte>);
|
||||
// var par2Type = assembly.GetType("System.Security.Cryptography.Asn1.AsnEncodingRules");
|
||||
// var asn1TagType = assembly.GetType("System.Security.Cryptography.Asn1.Asn1Tag");
|
||||
// var constructor = r.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, CallingConventions.HasThis,
|
||||
// new[] { par1Type, par2Type }, new ParameterModifier[0]);
|
||||
// if (constructor == null)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
// var readSequence = r.GetMethod("ReadSequence");
|
||||
// if (readSequence == null)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
// var throwIfNotEmpty = r.GetMethod("ThrowIfNotEmpty");
|
||||
// if (throwIfNotEmpty == null)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
// var readIntegerBytes = r.GetMethod("ReadIntegerBytes", BindingFlags.Instance | BindingFlags.Public, null, CallingConventions.HasThis, new Type[0], new ParameterModifier[0]);
|
||||
// if (readIntegerBytes == null)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
// var par1 = Expression.Parameter(par1Type, "data");
|
||||
// var derField = par2Type.GetField("DER");
|
||||
// var readerVar = Expression.Variable(r, "reader");
|
||||
// var sequenceReaderVar = Expression.Variable(r, "sequenceReader");
|
||||
// var rDerVar = Expression.Variable(typeof(ReadOnlyMemory<byte>), "rDer");
|
||||
// var sDerVar = Expression.Variable(typeof(ReadOnlyMemory<byte>), "sDer");
|
||||
// var sequenceField = asn1TagType.GetField("Sequence");
|
||||
// var expBlock = Expression.Block(new[] { readerVar, sequenceReaderVar, rDerVar, sDerVar },
|
||||
// Expression.Assign(readerVar, Expression.New(constructor, par1, Expression.Field(null, derField))),
|
||||
// Expression.Assign(sequenceReaderVar, Expression.Call(readerVar, readSequence, Expression.Field(null, sequenceField))),
|
||||
// Expression.Call(readerVar, throwIfNotEmpty),
|
||||
// Expression.Assign(rDerVar, Expression.Call(sequenceReaderVar, readIntegerBytes)),
|
||||
// Expression.Assign(sDerVar, Expression.Call(sequenceReaderVar, readIntegerBytes)),
|
||||
// Expression.Call(sequenceReaderVar, throwIfNotEmpty),
|
||||
// Expression.NewArrayInit(typeof(ReadOnlyMemory<byte>), rDerVar, sDerVar));
|
||||
// ReaderAsn = Expression.Lambda<Func<ReadOnlyMemory<byte>, ReadOnlyMemory<byte>[]>>(expBlock, par1).Compile();
|
||||
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Convert Der format of (r, s) to Ieee1363 format
|
||||
/// </summary>
|
||||
public static byte[] ConvertDerToIeee1363(ReadOnlySpan<byte> input, int fieldSizeBits)
|
||||
{
|
||||
int fieldSizeBytes = BitsToBytes(fieldSizeBits);
|
||||
int encodedSize = 2 * fieldSizeBytes;
|
||||
byte[] response = new byte[encodedSize];
|
||||
|
||||
ConvertDerToIeee1363(input, fieldSizeBits, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
internal static int ConvertDerToIeee1363(ReadOnlySpan<byte> input, int fieldSizeBits, Span<byte> destination)
|
||||
{
|
||||
int fieldSizeBytes = BitsToBytes(fieldSizeBits);
|
||||
int encodedSize = 2 * fieldSizeBytes;
|
||||
|
||||
Debug.Assert(destination.Length >= encodedSize);
|
||||
|
||||
try
|
||||
{
|
||||
AsnValueReader reader = new AsnValueReader(input, AsnEncodingRules.DER);
|
||||
AsnValueReader sequenceReader = reader.ReadSequence();
|
||||
reader.ThrowIfNotEmpty();
|
||||
ReadOnlySpan<byte> rDer = sequenceReader.ReadIntegerBytes();
|
||||
ReadOnlySpan<byte> sDer = sequenceReader.ReadIntegerBytes();
|
||||
sequenceReader.ThrowIfNotEmpty();
|
||||
|
||||
CopySignatureField(rDer, destination.Slice(0, fieldSizeBytes));
|
||||
CopySignatureField(sDer, destination.Slice(fieldSizeBytes, fieldSizeBytes));
|
||||
return encodedSize;
|
||||
}
|
||||
catch (AsnContentException e)
|
||||
{
|
||||
throw new CryptographicException("ASN1 corrupted data.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static int BitsToBytes(int bitLength)
|
||||
{
|
||||
int byteLength = (bitLength + 7) / 8;
|
||||
return byteLength;
|
||||
}
|
||||
|
||||
private static void CopySignatureField(ReadOnlySpan<byte> signatureField, Span<byte> response)
|
||||
{
|
||||
if (signatureField.Length > response.Length)
|
||||
{
|
||||
if (signatureField.Length != response.Length + 1 ||
|
||||
signatureField[0] != 0 ||
|
||||
signatureField[1] <= 0x7F)
|
||||
{
|
||||
// The only way this should be true is if the value required a zero-byte-pad.
|
||||
Debug.Fail($"A signature field was longer ({signatureField.Length}) than expected ({response.Length})");
|
||||
throw new CryptographicException();
|
||||
}
|
||||
|
||||
signatureField = signatureField.Slice(1);
|
||||
}
|
||||
|
||||
// If the field is too short then it needs to be prepended
|
||||
// with zeroes in the response. Since the array was already
|
||||
// zeroed out, just figure out where we need to start copying.
|
||||
int writeOffset = response.Length - signatureField.Length;
|
||||
response.Slice(0, writeOffset).Clear();
|
||||
signatureField.CopyTo(response.Slice(writeOffset));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -77,7 +77,7 @@ namespace PspCrypto.Security.Cryptography
|
|||
|
||||
protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm)
|
||||
{
|
||||
var dataSpan = data.AsSpan().Slice(offset, count);
|
||||
var dataSpan = new ReadOnlySpan<byte>(data, offset, count);
|
||||
if (hashAlgorithm == System.Security.Cryptography.HashAlgorithmName.SHA256)
|
||||
{
|
||||
return System.Security.Cryptography.SHA256.HashData(dataSpan);
|
||||
|
@ -127,8 +127,8 @@ namespace PspCrypto.Security.Cryptography
|
|||
Cofactor = _fpCurve.Cofactor.ToByteArrayUnsigned(),
|
||||
G = new System.Security.Cryptography.ECPoint
|
||||
{
|
||||
X = normalG.XCoord.ToBigInteger().ToByteArrayUnsigned(),
|
||||
Y = normalG.YCoord.ToBigInteger().ToByteArrayUnsigned()
|
||||
X = normalG.AffineXCoord.ToBigInteger().ToByteArrayUnsigned(),
|
||||
Y = normalG.AffineYCoord.ToBigInteger().ToByteArrayUnsigned()
|
||||
}
|
||||
};
|
||||
var parameters = new System.Security.Cryptography.ECParameters
|
||||
|
@ -138,21 +138,20 @@ namespace PspCrypto.Security.Cryptography
|
|||
if (includePrivateParameters && _ecKeyParameters is ECPrivateKeyParameters privateKeyParameters)
|
||||
{
|
||||
parameters.D = privateKeyParameters.D.ToByteArrayUnsigned();
|
||||
Console.WriteLine(privateKeyParameters.D.ToString(16).ToUpper());
|
||||
var publicKey = privateKeyParameters.Parameters.G.Multiply(privateKeyParameters.D).Normalize();
|
||||
var publicKey = _ecKeyParameters.Parameters.G.Multiply(privateKeyParameters.D).Normalize();
|
||||
parameters.Q = new System.Security.Cryptography.ECPoint
|
||||
{
|
||||
X = publicKey.XCoord.ToBigInteger().ToByteArrayUnsigned(),
|
||||
Y = publicKey.YCoord.ToBigInteger().ToByteArrayUnsigned()
|
||||
X = publicKey.AffineXCoord.ToBigInteger().ToByteArrayUnsigned(),
|
||||
Y = publicKey.AffineYCoord.ToBigInteger().ToByteArrayUnsigned()
|
||||
};
|
||||
}
|
||||
else if (_ecKeyParameters is ECPublicKeyParameters publicKeyParameters)
|
||||
{
|
||||
var publicKey = publicKeyParameters.Q;
|
||||
var publicKey = publicKeyParameters.Q.Normalize();
|
||||
parameters.Q = new System.Security.Cryptography.ECPoint
|
||||
{
|
||||
X = publicKey.XCoord.ToBigInteger().ToByteArrayUnsigned(),
|
||||
Y = publicKey.YCoord.ToBigInteger().ToByteArrayUnsigned()
|
||||
X = publicKey.AffineXCoord.ToBigInteger().ToByteArrayUnsigned(),
|
||||
Y = publicKey.AffineYCoord.ToBigInteger().ToByteArrayUnsigned()
|
||||
};
|
||||
}
|
||||
return parameters;
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace PspCrypto
|
||||
{
|
||||
public static class Utils
|
||||
{
|
||||
public static bool isEmpty(Span<byte> buf, int buf_size)
|
||||
public static bool IsEmpty(Span<byte> buf, int buf_size)
|
||||
{
|
||||
if (buf != null && buf.Length >= buf_size)
|
||||
{
|
||||
|
@ -21,58 +18,10 @@ namespace PspCrypto
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Re-interprets a span of bytes as a reference to structure of type T.
|
||||
/// The type may not contain pointers or references. This is checked at runtime in order to preserve type safety.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Supported only for platforms that support misaligned memory access or when the memory block is aligned by other means.
|
||||
/// </remarks>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T AsRef<T>(Span<byte> span)
|
||||
where T : struct
|
||||
{
|
||||
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"Cannot use type '{typeof(T)}'. Only value types without pointers or references are supported.");
|
||||
}
|
||||
|
||||
if (Unsafe.SizeOf<T>() > (uint)span.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("length");
|
||||
}
|
||||
return ref Unsafe.As<byte, T>(ref MemoryMarshal.GetReference(span));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Re-interprets a span of bytes as a reference to structure of type T.
|
||||
/// The type may not contain pointers or references. This is checked at runtime in order to preserve type safety.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Supported only for platforms that support misaligned memory access or when the memory block is aligned by other means.
|
||||
/// </remarks>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T AsRef<T>(ReadOnlySpan<byte> span)
|
||||
where T : struct
|
||||
{
|
||||
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"Cannot use type '{typeof(T)}'. Only value types without pointers or references are supported.");
|
||||
}
|
||||
|
||||
if (Unsafe.SizeOf<T>() > (uint)span.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("length");
|
||||
}
|
||||
return ref Unsafe.As<byte, T>(ref MemoryMarshal.GetReference(span));
|
||||
}
|
||||
|
||||
public static void BuildDrmBBMacFinal2(Span<byte> mac)
|
||||
{
|
||||
Span<byte> checksum = new byte[20 + 0x10];
|
||||
ref var aesHdr = ref AsRef<KIRKEngine.KIRK_AES128CBC_HEADER>(checksum);
|
||||
ref var aesHdr = ref MemoryMarshal.AsRef<KIRKEngine.KIRK_AES128CBC_HEADER>(checksum);
|
||||
aesHdr.mode = KIRKEngine.KIRK_MODE_ENCRYPT_CBC;
|
||||
aesHdr.keyseed = 0x63;
|
||||
aesHdr.data_size = 0x10;
|
||||
|
|
Loading…
Reference in New Issue