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.sceDrmBBCipherInit(out var ckey, 1, 2, npHdr.HeaderKey, vkey, 0);
|
||||||
AMCTRL.sceDrmBBCipherUpdate(ref ckey, psarBuff[0x40..], 0x60);
|
AMCTRL.sceDrmBBCipherUpdate(ref ckey, psarBuff[0x40..], 0x60);
|
||||||
AMCTRL.sceDrmBBCipherFinal(ref ckey);
|
AMCTRL.sceDrmBBCipherFinal(ref ckey);
|
||||||
npHdr = Utils.AsRef<NpUmdImgHdr>(psarBuff);
|
npHdr = MemoryMarshal.AsRef<NpUmdImgHdr>(psarBuff);
|
||||||
|
|
||||||
var lbasize = npHdr.Body.LbaEnd - npHdr.Body.LbaStart + 1;
|
var lbasize = npHdr.Body.LbaEnd - npHdr.Body.LbaStart + 1;
|
||||||
if (npHdr.BlockBasis == 0)
|
if (npHdr.BlockBasis == 0)
|
||||||
|
@ -1059,7 +1059,7 @@ namespace PbpResign
|
||||||
return false;
|
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)
|
if (npHdr.Magic0 == 0x4d55504e && npHdr.Magic1 == 0x474d4944)
|
||||||
{
|
{
|
||||||
|
@ -1189,7 +1189,7 @@ namespace PbpResign
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var pbpHdr = Utils.AsRef<PbpHeader>(hdr);
|
var pbpHdr = MemoryMarshal.AsRef<PbpHeader>(hdr);
|
||||||
if (pbpHdr.Sig != 0x50425000)
|
if (pbpHdr.Sig != 0x50425000)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Wrong pbp sig");
|
Console.WriteLine("Wrong pbp sig");
|
||||||
|
|
|
@ -67,7 +67,7 @@ namespace PspCrypto
|
||||||
static int Kirk4(Span<byte> buf, int size, int type)
|
static int Kirk4(Span<byte> buf, int size, int type)
|
||||||
{
|
{
|
||||||
int retv;
|
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.mode = KIRKEngine.KIRK_MODE_ENCRYPT_CBC;
|
||||||
hdr.keyseed = type;
|
hdr.keyseed = type;
|
||||||
hdr.data_size = size;
|
hdr.data_size = size;
|
||||||
|
@ -83,7 +83,7 @@ namespace PspCrypto
|
||||||
static int Kirk5(Span<byte> buf, int size)
|
static int Kirk5(Span<byte> buf, int size)
|
||||||
{
|
{
|
||||||
int retv;
|
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.mode = KIRKEngine.KIRK_MODE_ENCRYPT_CBC;
|
||||||
hdr.keyseed = 0x0100;
|
hdr.keyseed = 0x0100;
|
||||||
hdr.data_size = size;
|
hdr.data_size = size;
|
||||||
|
@ -99,7 +99,7 @@ namespace PspCrypto
|
||||||
static int Kirk7(Span<byte> buf, int size, int type)
|
static int Kirk7(Span<byte> buf, int size, int type)
|
||||||
{
|
{
|
||||||
int retv;
|
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.mode = KIRKEngine.KIRK_MODE_DECRYPT_CBC;
|
||||||
hdr.keyseed = type;
|
hdr.keyseed = type;
|
||||||
hdr.data_size = size;
|
hdr.data_size = size;
|
||||||
|
@ -115,7 +115,7 @@ namespace PspCrypto
|
||||||
static int Kirk8(Span<byte> buf, int size)
|
static int Kirk8(Span<byte> buf, int size)
|
||||||
{
|
{
|
||||||
int retv;
|
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.mode = KIRKEngine.KIRK_MODE_DECRYPT_CBC;
|
||||||
hdr.keyseed = 0x0100;
|
hdr.keyseed = 0x0100;
|
||||||
hdr.data_size = size;
|
hdr.data_size = size;
|
||||||
|
@ -553,7 +553,7 @@ namespace PspCrypto
|
||||||
|
|
||||||
public static int sceDrmBBMacFinal2(Span<byte> mkey, ReadOnlySpan<byte> hash, ReadOnlySpan<byte> vkey)
|
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];
|
byte[] tmp = new byte[16];
|
||||||
int kbuf;
|
int kbuf;
|
||||||
ref MAC_KEY macKey = ref MemoryMarshal.AsRef<MAC_KEY>(mkey);
|
ref MAC_KEY macKey = ref MemoryMarshal.AsRef<MAC_KEY>(mkey);
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace PspCrypto
|
||||||
|
|
||||||
data[..dataSize].CopyTo(pgdData[dataOffset..]);
|
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.Magic = 0x44475000;
|
||||||
pgdHdr.KeyIndex = keyIndex;
|
pgdHdr.KeyIndex = keyIndex;
|
||||||
pgdHdr.DrmType = drmType;
|
pgdHdr.DrmType = drmType;
|
||||||
|
@ -81,7 +81,7 @@ namespace PspCrypto
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the decryption parameters in the decrypted header.
|
// 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.DataSize = dataSize;
|
||||||
pgdDesc.BlockSize = blockSize;
|
pgdDesc.BlockSize = blockSize;
|
||||||
pgdDesc.DataOffset = dataOffset;
|
pgdDesc.DataOffset = dataOffset;
|
||||||
|
|
|
@ -169,7 +169,7 @@ namespace PspCrypto
|
||||||
{
|
{
|
||||||
throw new ArgumentException("stream too small", nameof(stream));
|
throw new ArgumentException("stream too small", nameof(stream));
|
||||||
}
|
}
|
||||||
var header = Utils.AsRef<PgdHeader>(hdr);
|
var header = MemoryMarshal.AsRef<PgdHeader>(hdr);
|
||||||
_keyIndex = header.KeyIndex;
|
_keyIndex = header.KeyIndex;
|
||||||
if (_keyIndex == 1)
|
if (_keyIndex == 1)
|
||||||
{
|
{
|
||||||
|
@ -234,7 +234,7 @@ namespace PspCrypto
|
||||||
throw new IOException("Wrong MAC 0x80");
|
throw new IOException("Wrong MAC 0x80");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Utils.isEmpty(_versionKey, 0x10))
|
if (!Utils.IsEmpty(_versionKey, 0x10))
|
||||||
{
|
{
|
||||||
ret = CheckBBMac(hdr, 0x70, _versionKey, header.Hash70, macType);
|
ret = CheckBBMac(hdr, 0x70, _versionKey, header.Hash70, macType);
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,7 @@ namespace PspCrypto
|
||||||
{
|
{
|
||||||
throw new IOException($"Error 0x{ret:X8}");
|
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)
|
if (desc.Version != 0)
|
||||||
{
|
{
|
||||||
throw new IOException($"Error 0x{8051020:X8}");
|
throw new IOException($"Error 0x{8051020:X8}");
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
using System;
|
using PspCrypto.Security.Cryptography;
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
|
||||||
using PspCrypto.Security.Cryptography;
|
|
||||||
|
|
||||||
namespace PspCrypto
|
namespace PspCrypto
|
||||||
{
|
{
|
||||||
|
@ -68,17 +65,6 @@ namespace PspCrypto
|
||||||
return new ECDsaManaged(par, ebootPbp, type);
|
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)
|
public static void SignNpImageHeader(Span<byte> npHdr)
|
||||||
{
|
{
|
||||||
var curve = SetCurve(KeyVault.ec_p, KeyVault.ec_a, KeyVault.ec_b2, KeyVault.ec_N2, KeyVault.Gx2,
|
var curve = SetCurve(KeyVault.ec_p, KeyVault.ec_a, KeyVault.ec_b2, KeyVault.ec_N2, KeyVault.Gx2,
|
||||||
|
@ -103,8 +89,8 @@ namespace PspCrypto
|
||||||
using var ecdsa = Create(curve, KeyVault.EdatPirv, KeyVault.EdatPx, KeyVault.EdatPy);
|
using var ecdsa = Create(curve, KeyVault.EdatPirv, KeyVault.EdatPx, KeyVault.EdatPy);
|
||||||
var sig = ecdsa.SignData(edat[..0x58].ToArray(), HashAlgorithmName.SHA1);
|
var sig = ecdsa.SignData(edat[..0x58].ToArray(), HashAlgorithmName.SHA1);
|
||||||
sig.CopyTo(edat[0x58..]);
|
sig.CopyTo(edat[0x58..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SignParamSfo(ReadOnlySpan<byte> param, Span<byte> sig)
|
public static void SignParamSfo(ReadOnlySpan<byte> param, Span<byte> sig)
|
||||||
{
|
{
|
||||||
var curve = SetCurve(KeyVault.ec_p, KeyVault.ec_a, KeyVault.ec_b2, KeyVault.ec_N2, KeyVault.Gx2,
|
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)
|
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);
|
// header_keys keys = Utils.AsRef<header_keys>(outbuff);
|
||||||
int chk_size;
|
int chk_size;
|
||||||
Aes k1;
|
Aes k1;
|
||||||
|
@ -817,7 +817,7 @@ namespace PspCrypto
|
||||||
|
|
||||||
static int kirk_CMD1(Span<byte> outbuff, ReadOnlySpan<byte> inbuff, int size)
|
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
|
// header_keys keys; //0-15 AES key, 16-31 CMAC key
|
||||||
Aes k1;
|
Aes k1;
|
||||||
|
|
||||||
|
@ -831,7 +831,7 @@ namespace PspCrypto
|
||||||
|
|
||||||
if (header.ecdsa_hash == 1)
|
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,
|
var curve = ECDsaHelper.SetCurve(KeyVault.ec_p, KeyVault.ec_a, KeyVault.ec_b1, KeyVault.ec_N1, KeyVault.Gx1,
|
||||||
KeyVault.Gy1);
|
KeyVault.Gy1);
|
||||||
unsafe
|
unsafe
|
||||||
|
@ -867,7 +867,7 @@ namespace PspCrypto
|
||||||
|
|
||||||
static int kirk_CMD4(Span<byte> outbuff, ReadOnlySpan<byte> inbuff, int size)
|
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;
|
byte[] key;
|
||||||
Aes aes;
|
Aes aes;
|
||||||
|
|
||||||
|
@ -892,7 +892,7 @@ namespace PspCrypto
|
||||||
|
|
||||||
static int kirk_CMD7(Span<byte> outbuff, ReadOnlySpan<byte> inbuff, int size)
|
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;
|
byte[] key;
|
||||||
Aes aes;
|
Aes aes;
|
||||||
|
|
||||||
|
@ -915,7 +915,7 @@ namespace PspCrypto
|
||||||
|
|
||||||
static int kirk_CMD10(ReadOnlySpan<byte> inbuff, int insize)
|
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
|
// header_keys keys; //0-15 AES key, 16-31 CMAC key
|
||||||
Span<byte> cmac_header_hash = stackalloc byte[16];
|
Span<byte> cmac_header_hash = stackalloc byte[16];
|
||||||
Span<byte> cmac_data_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)
|
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 (!is_kirk_initialized) return KIRK_NOT_INITIALIZED;
|
||||||
if (header.data_size == 0 || size == 0) return KIRK_DATA_SIZE_ZERO;
|
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)
|
static int kirk_CMD16(Span<byte> outbuff, int outsize, ReadOnlySpan<byte> inbuff, int insize)
|
||||||
{
|
{
|
||||||
byte[] dec_private = new byte[0x20];
|
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);
|
//ECDSA_SIG sig = BufferToStruct<ECDSA_SIG>(outbuff);
|
||||||
|
|
||||||
if (insize != 0x34) return KIRK_INVALID_SIZE;
|
if (insize != 0x34) return KIRK_INVALID_SIZE;
|
||||||
|
@ -1071,7 +1071,7 @@ namespace PspCrypto
|
||||||
|
|
||||||
static int kirk_CMD17(ReadOnlySpan<byte> inbuff, int insize)
|
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;
|
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)
|
static int Kirk8(Span<byte> buf, int size, int use_polling)
|
||||||
{
|
{
|
||||||
int retv;
|
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.mode = KIRKEngine.KIRK_MODE_DECRYPT_CBC;
|
||||||
hdr.keyseed = 0x0100;
|
hdr.keyseed = 0x0100;
|
||||||
hdr.data_size = size;
|
hdr.data_size = size;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,171 +1,170 @@
|
||||||
using Org.BouncyCastle.Crypto;
|
using Org.BouncyCastle.Crypto;
|
||||||
using Org.BouncyCastle.Crypto.Generators;
|
using Org.BouncyCastle.Crypto.Generators;
|
||||||
using Org.BouncyCastle.Crypto.Parameters;
|
using Org.BouncyCastle.Crypto.Parameters;
|
||||||
using Org.BouncyCastle.Crypto.Signers;
|
using Org.BouncyCastle.Crypto.Signers;
|
||||||
using Org.BouncyCastle.Math;
|
using Org.BouncyCastle.Math;
|
||||||
using Org.BouncyCastle.Math.EC;
|
using Org.BouncyCastle.Math.EC;
|
||||||
using Org.BouncyCastle.Security;
|
using Org.BouncyCastle.Security;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace PspCrypto.Security.Cryptography
|
namespace PspCrypto.Security.Cryptography
|
||||||
{
|
{
|
||||||
internal class ECDsaManaged : System.Security.Cryptography.ECDsa
|
internal class ECDsaManaged : System.Security.Cryptography.ECDsa
|
||||||
{
|
{
|
||||||
private ECKeyParameters _ecKeyParameters;
|
private ECKeyParameters _ecKeyParameters;
|
||||||
private readonly bool _ebootPbp;
|
private readonly bool _ebootPbp;
|
||||||
private readonly int _type;
|
private readonly int _type;
|
||||||
|
|
||||||
public ECDsaManaged()
|
public ECDsaManaged()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ECDsaManaged(System.Security.Cryptography.ECParameters parameters, bool ebootPbp, int type)
|
public ECDsaManaged(System.Security.Cryptography.ECParameters parameters, bool ebootPbp, int type)
|
||||||
{
|
{
|
||||||
_ebootPbp = ebootPbp;
|
_ebootPbp = ebootPbp;
|
||||||
_type = type;
|
_type = type;
|
||||||
var gx = new BigInteger(1, parameters.Curve.G.X);
|
var gx = new BigInteger(1, parameters.Curve.G.X);
|
||||||
var gy = new BigInteger(1, parameters.Curve.G.Y);
|
var gy = new BigInteger(1, parameters.Curve.G.Y);
|
||||||
var curve = ConvertECCurve(parameters.Curve);
|
var curve = ConvertECCurve(parameters.Curve);
|
||||||
var g = curve.CreatePoint(gx, gy);
|
var g = curve.CreatePoint(gx, gy);
|
||||||
var domainParameters = new ECDomainParameters(curve, g, curve.Order);
|
var domainParameters = new ECDomainParameters(curve, g, curve.Order);
|
||||||
if (parameters.D != null)
|
if (parameters.D != null)
|
||||||
{
|
{
|
||||||
var privateKey = new BigInteger(1, parameters.D);
|
var privateKey = new BigInteger(1, parameters.D);
|
||||||
_ecKeyParameters = new ECPrivateKeyParameters(privateKey, domainParameters);
|
_ecKeyParameters = new ECPrivateKeyParameters(privateKey, domainParameters);
|
||||||
}
|
}
|
||||||
else if (parameters.Q.X != null && parameters.Q.Y != null)
|
else if (parameters.Q.X != null && parameters.Q.Y != null)
|
||||||
{
|
{
|
||||||
var publicKey = curve.CreatePoint(new BigInteger(1, parameters.Q.X), new BigInteger(1, parameters.Q.Y));
|
var publicKey = curve.CreatePoint(new BigInteger(1, parameters.Q.X), new BigInteger(1, parameters.Q.Y));
|
||||||
_ecKeyParameters = new ECPublicKeyParameters(publicKey, domainParameters);
|
_ecKeyParameters = new ECPublicKeyParameters(publicKey, domainParameters);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new ArgumentException("invalid parameters", nameof(parameters));
|
throw new ArgumentException("invalid parameters", nameof(parameters));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] SignHash(byte[] hash)
|
public override byte[] SignHash(byte[] hash)
|
||||||
{
|
{
|
||||||
if (_ecKeyParameters is not ECPrivateKeyParameters)
|
if (_ecKeyParameters is not ECPrivateKeyParameters)
|
||||||
{
|
{
|
||||||
throw new ArgumentException("key is not private Key");
|
throw new ArgumentException("key is not private Key");
|
||||||
}
|
}
|
||||||
var signer = CreateSigner();
|
var signer = CreateSigner();
|
||||||
signer.Init(true, _ecKeyParameters);
|
signer.Init(true, _ecKeyParameters);
|
||||||
signer.BlockUpdate(hash);
|
signer.BlockUpdate(hash);
|
||||||
return signer.GenerateSignature();
|
return signer.GenerateSignature();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool VerifyHash(byte[] hash, byte[] signature)
|
public override bool VerifyHash(byte[] hash, byte[] signature)
|
||||||
{
|
{
|
||||||
var signer = CreateSigner();
|
var signer = CreateSigner();
|
||||||
if (_ecKeyParameters is ECPrivateKeyParameters ecPrivateKeyParameters)
|
if (_ecKeyParameters is ECPrivateKeyParameters ecPrivateKeyParameters)
|
||||||
{
|
{
|
||||||
var publicKey = new ECPublicKeyParameters(
|
var publicKey = new ECPublicKeyParameters(
|
||||||
ecPrivateKeyParameters.Parameters.G.Multiply(ecPrivateKeyParameters.D),
|
ecPrivateKeyParameters.Parameters.G.Multiply(ecPrivateKeyParameters.D),
|
||||||
ecPrivateKeyParameters.Parameters);
|
ecPrivateKeyParameters.Parameters);
|
||||||
signer.Init(false, publicKey);
|
signer.Init(false, publicKey);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
signer.Init(false, _ecKeyParameters);
|
signer.Init(false, _ecKeyParameters);
|
||||||
}
|
}
|
||||||
signer.BlockUpdate(hash);
|
signer.BlockUpdate(hash);
|
||||||
return signer.VerifySignature(signature);
|
return signer.VerifySignature(signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm)
|
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)
|
if (hashAlgorithm == System.Security.Cryptography.HashAlgorithmName.SHA256)
|
||||||
{
|
{
|
||||||
return System.Security.Cryptography.SHA256.HashData(dataSpan);
|
return System.Security.Cryptography.SHA256.HashData(dataSpan);
|
||||||
}
|
}
|
||||||
else if (hashAlgorithm == System.Security.Cryptography.HashAlgorithmName.SHA1)
|
else if (hashAlgorithm == System.Security.Cryptography.HashAlgorithmName.SHA1)
|
||||||
{
|
{
|
||||||
return System.Security.Cryptography.SHA1.HashData(dataSpan);
|
return System.Security.Cryptography.SHA1.HashData(dataSpan);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new NotSupportedException($"{hashAlgorithm} not supported");
|
throw new NotSupportedException($"{hashAlgorithm} not supported");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISigner CreateSigner()
|
private ISigner CreateSigner()
|
||||||
{
|
{
|
||||||
IDigest digest = DigestUtilities.GetDigest("NONE");
|
IDigest digest = DigestUtilities.GetDigest("NONE");
|
||||||
IDsa dsa = _ebootPbp ? new ECDsaSigner(new EbootPbpKCalculator(_type)) : new ECDsaSigner();
|
IDsa dsa = _ebootPbp ? new ECDsaSigner(new EbootPbpKCalculator(_type)) : new ECDsaSigner();
|
||||||
var signer = new DsaDigestSigner(dsa, digest, PlainDsaEncoding.Instance);
|
var signer = new DsaDigestSigner(dsa, digest, PlainDsaEncoding.Instance);
|
||||||
return signer;
|
return signer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private FpCurve _fpCurve;
|
private FpCurve _fpCurve;
|
||||||
|
|
||||||
public override void GenerateKey(System.Security.Cryptography.ECCurve curve)
|
public override void GenerateKey(System.Security.Cryptography.ECCurve curve)
|
||||||
{
|
{
|
||||||
_fpCurve = ConvertECCurve(curve);
|
_fpCurve = ConvertECCurve(curve);
|
||||||
var gx = new BigInteger(1, curve.G.X);
|
var gx = new BigInteger(1, curve.G.X);
|
||||||
var gy = new BigInteger(1, curve.G.Y);
|
var gy = new BigInteger(1, curve.G.Y);
|
||||||
var g = _fpCurve.CreatePoint(gx, gy);
|
var g = _fpCurve.CreatePoint(gx, gy);
|
||||||
var domainParameters = new ECDomainParameters(_fpCurve, g, _fpCurve.Order);
|
var domainParameters = new ECDomainParameters(_fpCurve, g, _fpCurve.Order);
|
||||||
var gen = new ECKeyPairGenerator();
|
var gen = new ECKeyPairGenerator();
|
||||||
gen.Init(new ECKeyGenerationParameters(domainParameters, new SecureRandom()));
|
gen.Init(new ECKeyGenerationParameters(domainParameters, new SecureRandom()));
|
||||||
var keyPair = gen.GenerateKeyPair();
|
var keyPair = gen.GenerateKeyPair();
|
||||||
_ecKeyParameters = (ECKeyParameters)keyPair.Private;
|
_ecKeyParameters = (ECKeyParameters)keyPair.Private;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override System.Security.Cryptography.ECParameters ExportExplicitParameters(bool includePrivateParameters)
|
public override System.Security.Cryptography.ECParameters ExportExplicitParameters(bool includePrivateParameters)
|
||||||
{
|
{
|
||||||
var normalG = _ecKeyParameters.Parameters.G;
|
var normalG = _ecKeyParameters.Parameters.G;
|
||||||
var curve = new System.Security.Cryptography.ECCurve
|
var curve = new System.Security.Cryptography.ECCurve
|
||||||
{
|
{
|
||||||
A = _fpCurve.A.ToBigInteger().ToByteArrayUnsigned(),
|
A = _fpCurve.A.ToBigInteger().ToByteArrayUnsigned(),
|
||||||
B = _fpCurve.B.ToBigInteger().ToByteArrayUnsigned(),
|
B = _fpCurve.B.ToBigInteger().ToByteArrayUnsigned(),
|
||||||
Prime = _fpCurve.Q.ToByteArrayUnsigned(),
|
Prime = _fpCurve.Q.ToByteArrayUnsigned(),
|
||||||
Order = _fpCurve.Order.ToByteArrayUnsigned(),
|
Order = _fpCurve.Order.ToByteArrayUnsigned(),
|
||||||
Cofactor = _fpCurve.Cofactor.ToByteArrayUnsigned(),
|
Cofactor = _fpCurve.Cofactor.ToByteArrayUnsigned(),
|
||||||
G = new System.Security.Cryptography.ECPoint
|
G = new System.Security.Cryptography.ECPoint
|
||||||
{
|
{
|
||||||
X = normalG.XCoord.ToBigInteger().ToByteArrayUnsigned(),
|
X = normalG.AffineXCoord.ToBigInteger().ToByteArrayUnsigned(),
|
||||||
Y = normalG.YCoord.ToBigInteger().ToByteArrayUnsigned()
|
Y = normalG.AffineYCoord.ToBigInteger().ToByteArrayUnsigned()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var parameters = new System.Security.Cryptography.ECParameters
|
var parameters = new System.Security.Cryptography.ECParameters
|
||||||
{
|
{
|
||||||
Curve = curve
|
Curve = curve
|
||||||
};
|
};
|
||||||
if (includePrivateParameters && _ecKeyParameters is ECPrivateKeyParameters privateKeyParameters)
|
if (includePrivateParameters && _ecKeyParameters is ECPrivateKeyParameters privateKeyParameters)
|
||||||
{
|
{
|
||||||
parameters.D = privateKeyParameters.D.ToByteArrayUnsigned();
|
parameters.D = privateKeyParameters.D.ToByteArrayUnsigned();
|
||||||
Console.WriteLine(privateKeyParameters.D.ToString(16).ToUpper());
|
var publicKey = _ecKeyParameters.Parameters.G.Multiply(privateKeyParameters.D).Normalize();
|
||||||
var publicKey = privateKeyParameters.Parameters.G.Multiply(privateKeyParameters.D).Normalize();
|
parameters.Q = new System.Security.Cryptography.ECPoint
|
||||||
parameters.Q = new System.Security.Cryptography.ECPoint
|
{
|
||||||
{
|
X = publicKey.AffineXCoord.ToBigInteger().ToByteArrayUnsigned(),
|
||||||
X = publicKey.XCoord.ToBigInteger().ToByteArrayUnsigned(),
|
Y = publicKey.AffineYCoord.ToBigInteger().ToByteArrayUnsigned()
|
||||||
Y = publicKey.YCoord.ToBigInteger().ToByteArrayUnsigned()
|
};
|
||||||
};
|
}
|
||||||
}
|
else if (_ecKeyParameters is ECPublicKeyParameters publicKeyParameters)
|
||||||
else if (_ecKeyParameters is ECPublicKeyParameters publicKeyParameters)
|
{
|
||||||
{
|
var publicKey = publicKeyParameters.Q.Normalize();
|
||||||
var publicKey = publicKeyParameters.Q;
|
parameters.Q = new System.Security.Cryptography.ECPoint
|
||||||
parameters.Q = new System.Security.Cryptography.ECPoint
|
{
|
||||||
{
|
X = publicKey.AffineXCoord.ToBigInteger().ToByteArrayUnsigned(),
|
||||||
X = publicKey.XCoord.ToBigInteger().ToByteArrayUnsigned(),
|
Y = publicKey.AffineYCoord.ToBigInteger().ToByteArrayUnsigned()
|
||||||
Y = publicKey.YCoord.ToBigInteger().ToByteArrayUnsigned()
|
};
|
||||||
};
|
}
|
||||||
}
|
return parameters;
|
||||||
return parameters;
|
}
|
||||||
}
|
|
||||||
|
private static FpCurve ConvertECCurve(System.Security.Cryptography.ECCurve curve)
|
||||||
private static FpCurve ConvertECCurve(System.Security.Cryptography.ECCurve curve)
|
{
|
||||||
{
|
var p = new BigInteger(1, curve.Prime);
|
||||||
var p = new BigInteger(1, curve.Prime);
|
var a = new BigInteger(1, curve.A);
|
||||||
var a = new BigInteger(1, curve.A);
|
var b = new BigInteger(1, curve.B);
|
||||||
var b = new BigInteger(1, curve.B);
|
var n = new BigInteger(1, curve.Order);
|
||||||
var n = new BigInteger(1, curve.Order);
|
var fpCurve = new FpCurve(p, a, b, n, BigInteger.One);
|
||||||
var fpCurve = new FpCurve(p, a, b, n, BigInteger.One);
|
return fpCurve;
|
||||||
return fpCurve;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,103 +1,103 @@
|
||||||
using Org.BouncyCastle.Crypto.Digests;
|
using Org.BouncyCastle.Crypto.Digests;
|
||||||
using Org.BouncyCastle.Crypto.Macs;
|
using Org.BouncyCastle.Crypto.Macs;
|
||||||
using Org.BouncyCastle.Crypto.Parameters;
|
using Org.BouncyCastle.Crypto.Parameters;
|
||||||
using Org.BouncyCastle.Crypto.Signers;
|
using Org.BouncyCastle.Crypto.Signers;
|
||||||
using Org.BouncyCastle.Math;
|
using Org.BouncyCastle.Math;
|
||||||
using Org.BouncyCastle.Security;
|
using Org.BouncyCastle.Security;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace PspCrypto.Security.Cryptography
|
namespace PspCrypto.Security.Cryptography
|
||||||
{
|
{
|
||||||
internal class EbootPbpKCalculator : IDsaKCalculator
|
internal class EbootPbpKCalculator : IDsaKCalculator
|
||||||
{
|
{
|
||||||
private int _type;
|
private int _type;
|
||||||
|
|
||||||
private BigInteger _n;
|
private BigInteger _n;
|
||||||
|
|
||||||
public EbootPbpKCalculator(int type)
|
public EbootPbpKCalculator(int type)
|
||||||
{
|
{
|
||||||
_type = type;
|
_type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDeterministic => true;
|
public bool IsDeterministic => true;
|
||||||
|
|
||||||
private readonly Memory<byte> _hash = new byte[0x40];
|
private readonly Memory<byte> _hash = new byte[0x40];
|
||||||
|
|
||||||
public void Init(BigInteger n, SecureRandom random)
|
public void Init(BigInteger n, SecureRandom random)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
public void Init(BigInteger n, BigInteger d, byte[] message)
|
public void Init(BigInteger n, BigInteger d, byte[] message)
|
||||||
{
|
{
|
||||||
_n = n;
|
_n = n;
|
||||||
Span<byte> hmacIn = stackalloc byte[0x38];
|
Span<byte> hmacIn = stackalloc byte[0x38];
|
||||||
message[..0x1C].CopyTo(hmacIn);
|
message[..0x1C].CopyTo(hmacIn);
|
||||||
KeyVault.Eboot_priv[_type].CopyTo(hmacIn[0x1C..]);
|
KeyVault.Eboot_priv[_type].CopyTo(hmacIn[0x1C..]);
|
||||||
|
|
||||||
var hmac = new HMac(new Sha256Digest());
|
var hmac = new HMac(new Sha256Digest());
|
||||||
hmac.Init(new KeyParameter(KeyVault.Eboot_hmacKey));
|
hmac.Init(new KeyParameter(KeyVault.Eboot_hmacKey));
|
||||||
hmac.BlockUpdate(hmacIn);
|
hmac.BlockUpdate(hmacIn);
|
||||||
var hmac_hash_iv = new byte[hmac.GetMacSize()];
|
var hmac_hash_iv = new byte[hmac.GetMacSize()];
|
||||||
hmac.DoFinal(hmac_hash_iv);
|
hmac.DoFinal(hmac_hash_iv);
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ret = can_be_reversed_80C17A(message, 0x1c, hmac_hash_iv, _hash.Span);
|
ret = can_be_reversed_80C17A(message, 0x1c, hmac_hash_iv, _hash.Span);
|
||||||
if (ret != 0 || (ret = can_be_reversed_80C17A(message, 0x1c, hmac_hash_iv, _hash.Span[0x20..])) != 0)
|
if (ret != 0 || (ret = can_be_reversed_80C17A(message, 0x1c, hmac_hash_iv, _hash.Span[0x20..])) != 0)
|
||||||
{
|
{
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (ret != 0);
|
} while (ret != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BigInteger NextK()
|
public BigInteger NextK()
|
||||||
{
|
{
|
||||||
var bn = new BigInteger(1, _hash.Span[..0x3c]);
|
var bn = new BigInteger(1, _hash.Span[..0x3c]);
|
||||||
var ret = bn.Mod(_n);
|
var ret = bn.Mod(_n);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static int can_be_reversed_80C17A(Span<byte> src, int some_size, Span<byte> iv,
|
private static int can_be_reversed_80C17A(Span<byte> src, int some_size, Span<byte> iv,
|
||||||
Span<byte> src_xored_digest)
|
Span<byte> src_xored_digest)
|
||||||
{
|
{
|
||||||
Span<byte> src_xored = stackalloc byte[0x20];
|
Span<byte> src_xored = stackalloc byte[0x20];
|
||||||
iv.CopyTo(src_xored);
|
iv.CopyTo(src_xored);
|
||||||
|
|
||||||
if (some_size > 0x20)
|
if (some_size > 0x20)
|
||||||
{
|
{
|
||||||
return 0x12;
|
return 0x12;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < some_size; i++)
|
for (int i = 0; i < some_size; i++)
|
||||||
{
|
{
|
||||||
src_xored[i] ^= src[i];
|
src_xored[i] ^= src[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
using var sha256 = System.Security.Cryptography.SHA256.Create();
|
using var sha256 = System.Security.Cryptography.SHA256.Create();
|
||||||
var hash = sha256.ComputeHash(src_xored.ToArray());
|
var hash = sha256.ComputeHash(src_xored.ToArray());
|
||||||
hash.CopyTo(src_xored_digest);
|
hash.CopyTo(src_xored_digest);
|
||||||
|
|
||||||
for (int i = 0; i < 0x20; i++)
|
for (int i = 0; i < 0x20; i++)
|
||||||
{
|
{
|
||||||
iv[i] ^= src_xored_digest[i];
|
iv[i] ^= src_xored_digest[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 0x20; i++)
|
for (int i = 0; i < 0x20; i++)
|
||||||
{
|
{
|
||||||
if (iv[i] != 0xFF)
|
if (iv[i] != 0xFF)
|
||||||
{
|
{
|
||||||
iv[i] += 1;
|
iv[i] += 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
iv[i] = 0;
|
iv[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PspCrypto
|
namespace PspCrypto
|
||||||
{
|
{
|
||||||
public static class Utils
|
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)
|
if (buf != null && buf.Length >= buf_size)
|
||||||
{
|
{
|
||||||
|
@ -21,58 +18,10 @@ namespace PspCrypto
|
||||||
return true;
|
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)
|
public static void BuildDrmBBMacFinal2(Span<byte> mac)
|
||||||
{
|
{
|
||||||
Span<byte> checksum = new byte[20 + 0x10];
|
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.mode = KIRKEngine.KIRK_MODE_ENCRYPT_CBC;
|
||||||
aesHdr.keyseed = 0x63;
|
aesHdr.keyseed = 0x63;
|
||||||
aesHdr.data_size = 0x10;
|
aesHdr.data_size = 0x10;
|
||||||
|
|
Loading…
Reference in New Issue