diff --git a/PbpResign/Program.cs b/PbpResign/Program.cs index 55f3cab..19ceffc 100644 --- a/PbpResign/Program.cs +++ b/PbpResign/Program.cs @@ -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(psarBuff); + npHdr = MemoryMarshal.AsRef(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(psarBuff); + ref var npHdr = ref MemoryMarshal.AsRef(psarBuff); if (npHdr.Magic0 == 0x4d55504e && npHdr.Magic1 == 0x474d4944) { @@ -1189,7 +1189,7 @@ namespace PbpResign return; } - var pbpHdr = Utils.AsRef(hdr); + var pbpHdr = MemoryMarshal.AsRef(hdr); if (pbpHdr.Sig != 0x50425000) { Console.WriteLine("Wrong pbp sig"); diff --git a/PspCrypto/AMCTRL.cs b/PspCrypto/AMCTRL.cs index 515fc7d..36ac756 100644 --- a/PspCrypto/AMCTRL.cs +++ b/PspCrypto/AMCTRL.cs @@ -67,7 +67,7 @@ namespace PspCrypto static int Kirk4(Span buf, int size, int type) { int retv; - ref var hdr = ref Utils.AsRef(buf); + ref var hdr = ref MemoryMarshal.AsRef(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 buf, int size) { int retv; - ref var hdr = ref Utils.AsRef(buf); + ref var hdr = ref MemoryMarshal.AsRef(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 buf, int size, int type) { int retv; - ref var hdr = ref Utils.AsRef(buf); + ref var hdr = ref MemoryMarshal.AsRef(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 buf, int size) { int retv; - ref var hdr = ref Utils.AsRef(buf); + ref var hdr = ref MemoryMarshal.AsRef(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 mkey, ReadOnlySpan hash, ReadOnlySpan vkey) { - int i, retv, type; + int retv, type; byte[] tmp = new byte[16]; int kbuf; ref MAC_KEY macKey = ref MemoryMarshal.AsRef(mkey); diff --git a/PspCrypto/DNASHelper.cs b/PspCrypto/DNASHelper.cs index 3baf241..088c79a 100644 --- a/PspCrypto/DNASHelper.cs +++ b/PspCrypto/DNASHelper.cs @@ -35,7 +35,7 @@ namespace PspCrypto data[..dataSize].CopyTo(pgdData[dataOffset..]); - ref var pgdHdr = ref Utils.AsRef(pgdData); + ref var pgdHdr = ref MemoryMarshal.AsRef(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(pgdHdr.PgdDesc); + ref var pgdDesc = ref MemoryMarshal.AsRef(pgdHdr.PgdDesc); pgdDesc.DataSize = dataSize; pgdDesc.BlockSize = blockSize; pgdDesc.DataOffset = dataOffset; diff --git a/PspCrypto/DNASStream.cs b/PspCrypto/DNASStream.cs index ba005d4..f3e6093 100644 --- a/PspCrypto/DNASStream.cs +++ b/PspCrypto/DNASStream.cs @@ -169,7 +169,7 @@ namespace PspCrypto { throw new ArgumentException("stream too small", nameof(stream)); } - var header = Utils.AsRef(hdr); + var header = MemoryMarshal.AsRef(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(header.PgdDesc); + var desc = MemoryMarshal.AsRef(header.PgdDesc); if (desc.Version != 0) { throw new IOException($"Error 0x{8051020:X8}"); diff --git a/PspCrypto/ECDsaHelper.cs b/PspCrypto/ECDsaHelper.cs index ad98625..ae97e50 100644 --- a/PspCrypto/ECDsaHelper.cs +++ b/PspCrypto/ECDsaHelper.cs @@ -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 npHdr) { 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); var sig = ecdsa.SignData(edat[..0x58].ToArray(), HashAlgorithmName.SHA1); sig.CopyTo(edat[0x58..]); - } - + } + public static void SignParamSfo(ReadOnlySpan param, Span sig) { var curve = SetCurve(KeyVault.ec_p, KeyVault.ec_a, KeyVault.ec_b2, KeyVault.ec_N2, KeyVault.Gx2, diff --git a/PspCrypto/Interop/Interop.Bignum.cs b/PspCrypto/Interop/Interop.Bignum.cs deleted file mode 100644 index c9c45a7..0000000 --- a/PspCrypto/Interop/Interop.Bignum.cs +++ /dev/null @@ -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; - } - } -} diff --git a/PspCrypto/Interop/Interop.ERR.cs b/PspCrypto/Interop/Interop.ERR.cs deleted file mode 100644 index ee07020..0000000 --- a/PspCrypto/Interop/Interop.ERR.cs +++ /dev/null @@ -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; - } - } - } -} diff --git a/PspCrypto/Interop/Interop.EcDsa.ImportExport.cs b/PspCrypto/Interop/Interop.EcDsa.ImportExport.cs deleted file mode 100644 index 3bdf33f..0000000 --- a/PspCrypto/Interop/Interop.EcDsa.ImportExport.cs +++ /dev/null @@ -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; - } - } -} diff --git a/PspCrypto/Interop/Interop.EcDsa.cs b/PspCrypto/Interop/Interop.EcDsa.cs deleted file mode 100644 index e3c909d..0000000 --- a/PspCrypto/Interop/Interop.EcDsa.cs +++ /dev/null @@ -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 dgst, Span sig, [In, Out] ref int siglen, - ReadOnlySpan kinv, ReadOnlySpan 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 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); - } -} diff --git a/PspCrypto/Interop/Interop.EcKey.cs b/PspCrypto/Interop/Interop.EcKey.cs deleted file mode 100644 index 62625d7..0000000 --- a/PspCrypto/Interop/Interop.EcKey.cs +++ /dev/null @@ -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); - } -} diff --git a/PspCrypto/KIRKEngine.cs b/PspCrypto/KIRKEngine.cs index 33a2db7..b46f15b 100644 --- a/PspCrypto/KIRKEngine.cs +++ b/PspCrypto/KIRKEngine.cs @@ -762,7 +762,7 @@ namespace PspCrypto static int kirk_CMD0(Span outbuff, ReadOnlySpan inbuff, int size, bool generate_trash) { - KIRK_CMD1_HEADER header = Utils.AsRef(outbuff); + KIRK_CMD1_HEADER header = MemoryMarshal.AsRef(outbuff); // header_keys keys = Utils.AsRef(outbuff); int chk_size; Aes k1; @@ -817,7 +817,7 @@ namespace PspCrypto static int kirk_CMD1(Span outbuff, ReadOnlySpan inbuff, int size) { - KIRK_CMD1_HEADER header = Utils.AsRef(inbuff); + KIRK_CMD1_HEADER header = MemoryMarshal.AsRef(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(inbuff); + KIRK_CMD1_ECDSA_HEADER eheader = MemoryMarshal.AsRef(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 outbuff, ReadOnlySpan inbuff, int size) { - KIRK_AES128CBC_HEADER header = Utils.AsRef(inbuff); + KIRK_AES128CBC_HEADER header = MemoryMarshal.AsRef(inbuff); byte[] key; Aes aes; @@ -892,7 +892,7 @@ namespace PspCrypto static int kirk_CMD7(Span outbuff, ReadOnlySpan inbuff, int size) { - KIRK_AES128CBC_HEADER header = Utils.AsRef(inbuff); + KIRK_AES128CBC_HEADER header = MemoryMarshal.AsRef(inbuff); byte[] key; Aes aes; @@ -915,7 +915,7 @@ namespace PspCrypto static int kirk_CMD10(ReadOnlySpan inbuff, int insize) { - KIRK_CMD1_HEADER header = Utils.AsRef(inbuff); + KIRK_CMD1_HEADER header = MemoryMarshal.AsRef(inbuff); // header_keys keys; //0-15 AES key, 16-31 CMAC key Span cmac_header_hash = stackalloc byte[16]; Span cmac_data_hash = stackalloc byte[16]; @@ -951,7 +951,7 @@ namespace PspCrypto static int kirk_CMD11(Span outbuff, ReadOnlySpan inbuff, int size) { - KIRK_SHA1_HEADER header = Utils.AsRef(inbuff); + KIRK_SHA1_HEADER header = MemoryMarshal.AsRef(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 outbuff, int outsize, ReadOnlySpan inbuff, int insize) { byte[] dec_private = new byte[0x20]; - KIRK_CMD16_BUFFER signbuf = Utils.AsRef(inbuff); + KIRK_CMD16_BUFFER signbuf = MemoryMarshal.AsRef(inbuff); //ECDSA_SIG sig = BufferToStruct(outbuff); if (insize != 0x34) return KIRK_INVALID_SIZE; @@ -1071,7 +1071,7 @@ namespace PspCrypto static int kirk_CMD17(ReadOnlySpan inbuff, int insize) { - KIRK_CMD17_BUFFER sig = Utils.AsRef(inbuff); + KIRK_CMD17_BUFFER sig = MemoryMarshal.AsRef(inbuff); if (insize != 0x64) return KIRK_INVALID_SIZE; diff --git a/PspCrypto/RijndaelMod.cs b/PspCrypto/RijndaelMod.cs deleted file mode 100644 index 1061057..0000000 --- a/PspCrypto/RijndaelMod.cs +++ /dev/null @@ -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; - } -} diff --git a/PspCrypto/RijndaelModTransform.cs b/PspCrypto/RijndaelModTransform.cs deleted file mode 100644 index c49bbf2..0000000 --- a/PspCrypto/RijndaelModTransform.cs +++ /dev/null @@ -1,1099 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.Contracts; -using System.Security; -using System.Security.Cryptography; -using System.Text; - -namespace PspCrypto -{ - class RijndaelModTransform : ICryptoTransform - { - private bool _isEncrypt; - - - private int _blockSizeBits; - private int _blockSizeBytes; - private int _inputBlockSize; - private int _outputBlockSize; - - - private int[] _encryptKeyExpansion; - private int[] _decryptKeyExpansion; - - private int _Nr; - private int _Nb; - private int _Nk; - - private int[] _encryptindex = null; - private int[] _decryptindex = null; - - private int[] _lastBlockBuffer; - private byte[] _depadBuffer; - private byte[] _shiftRegister; - - internal RijndaelModTransform(byte[] rgbKey, - int blockSize, bool isEncrypt) - { - if (rgbKey == null) - throw new ArgumentNullException(nameof(rgbKey)); - Contract.EndContractBlock(); - - _blockSizeBits = blockSize; - _blockSizeBytes = blockSize / 8; - _isEncrypt = isEncrypt; - _Nb = blockSize / 32; - _Nk = rgbKey.Length / 4; - - int S1 = _Nb > 6 ? 3 : 2; - int S2 = _Nb > 6 ? 4 : 3; - - - // Precompute the modulus operations: these are performance killers when called frequently - int[] encryptindex1 = new int[_Nb]; - int[] encryptindex2 = new int[_Nb]; - int[] encryptindex3 = new int[_Nb]; - - int[] decryptindex1 = new int[_Nb]; - int[] decryptindex2 = new int[_Nb]; - int[] decryptindex3 = new int[_Nb]; - - - for (int j = 0; j < _Nb; j++) - { - encryptindex1[j] = (j + 1) % _Nb; - encryptindex2[j] = (j + S1) % _Nb; - encryptindex3[j] = (j + S2) % _Nb; - decryptindex1[j] = (j - 1 + _Nb) % _Nb; - decryptindex2[j] = (j - S1 + _Nb) % _Nb; - decryptindex3[j] = (j - S2 + _Nb) % _Nb; - } - - - _encryptindex = new int[_Nb * 3]; - Array.Copy(encryptindex1, 0, _encryptindex, 0, _Nb); - Array.Copy(encryptindex2, 0, _encryptindex, _Nb, _Nb); - Array.Copy(encryptindex3, 0, _encryptindex, _Nb * 2, _Nb); - - _decryptindex = new int[_Nb * 3]; - Array.Copy(decryptindex1, 0, _decryptindex, 0, _Nb); - Array.Copy(decryptindex2, 0, _decryptindex, _Nb, _Nb); - Array.Copy(decryptindex3, 0, _decryptindex, _Nb * 2, _Nb); - - _inputBlockSize = _blockSizeBytes; - _outputBlockSize = _blockSizeBytes; - - - GenerateKeyExpansion(rgbKey); - } - - public void Dispose() - { - Dispose(true); - } - - private void Dispose(bool disposing) - { - if (disposing) - { - // We need to always zeroize the following fields because they contain sensitive data - if (_lastBlockBuffer != null) - { - Array.Clear(_lastBlockBuffer, 0, _lastBlockBuffer.Length); - _lastBlockBuffer = null; - } - if (_encryptKeyExpansion != null) - { - Array.Clear(_encryptKeyExpansion, 0, _encryptKeyExpansion.Length); - _encryptKeyExpansion = null; - } - if (_decryptKeyExpansion != null) - { - Array.Clear(_decryptKeyExpansion, 0, _decryptKeyExpansion.Length); - _decryptKeyExpansion = null; - } - if (_depadBuffer != null) - { - Array.Clear(_depadBuffer, 0, _depadBuffer.Length); - _depadBuffer = null; - } - if (_shiftRegister != null) - { - Array.Clear(_shiftRegister, 0, _shiftRegister.Length); - _shiftRegister = null; - } - } - } - public bool CanReuseTransform => true; - public bool CanTransformMultipleBlocks => true; - public int InputBlockSize => _inputBlockSize; - public int OutputBlockSize => _outputBlockSize; - - public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) - { // Note: special handling required if decrypting & using padding because the padding adds to the end of the last - // block, we have to buffer an entire block's worth of bytes in case what I just transformed turns out to be - // the last block Then in TransformFinalBlock we strip off the padding. - - if (inputBuffer == null) throw new ArgumentNullException(nameof(inputBuffer)); - if (outputBuffer == null) throw new ArgumentNullException(nameof(outputBuffer)); - if (inputOffset < 0) throw new ArgumentOutOfRangeException(nameof(inputOffset)); - if (inputCount <= 0 || (inputCount % InputBlockSize != 0) || (inputCount > inputBuffer.Length)) throw new ArgumentException("Argument_InvalidValue"); - if ((inputBuffer.Length - inputCount) < inputOffset) throw new ArgumentException("Argument_InvalidOffLen"); - Contract.EndContractBlock(); - - if (_isEncrypt) - { - return EncryptData(inputBuffer,inputOffset,inputCount,ref outputBuffer,outputOffset,false); - } - else - { - return DecryptData(inputBuffer, inputOffset, inputCount, ref outputBuffer, outputOffset, false); - } - } - - public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) - { - if (inputBuffer == null) throw new ArgumentNullException(nameof(inputBuffer)); - if (inputOffset < 0) throw new ArgumentOutOfRangeException(nameof(inputOffset), "ArgumentOutOfRange_NeedNonNegNum"); - if (inputCount < 0 || (inputCount > inputBuffer.Length)) throw new ArgumentException("Argument_InvalidValue"); - if ((inputBuffer.Length - inputCount) < inputOffset) throw new ArgumentException("Argument_InvalidOffLen"); - Contract.EndContractBlock(); - if (_isEncrypt) - { - byte[] transformedBytes = null; - EncryptData(inputBuffer, - inputOffset, - inputCount, - ref transformedBytes, - 0, - true); - return transformedBytes; - } - else - { - if (inputCount % InputBlockSize != 0) - throw new CryptographicException("Cryptography_SSD_InvalidDataSize"); - byte[] transformedBytes = null; - DecryptData(inputBuffer, - inputOffset, - inputCount, - ref transformedBytes, - 0, - true); - return transformedBytes; - } - } - - [SecuritySafeCritical] - private unsafe int EncryptData(byte[] inputBuffer, - int inputOffset, - int inputCount, - ref byte[] outputBuffer, - int outputOffset, - bool fLast) - { - - if (inputBuffer.Length < inputOffset + inputCount) - throw new CryptographicException("Cryptography_InsufficientBuffer"); - - int lonelyBytes = inputCount % _inputBlockSize; - - int workBaseIndex = inputOffset, index = 0; - - if (lonelyBytes != 0) - throw new CryptographicException("Cryptography_SSE_InvalidDataSize"); - - if (outputBuffer == null) - { - outputBuffer = new byte[inputCount]; - outputOffset = 0; - } - else - { - if (outputBuffer.Length - outputOffset < inputCount) - throw new CryptographicException("Cryptography_InsufficientBuffer"); - } - - fixed (int* encryptindex = _encryptindex) - { - fixed (int* encryptKeyExpansion = _encryptKeyExpansion) - { - fixed (int* T = s_T) - { - fixed (int* TF = s_TF) - { - int* work = stackalloc int[_Nb]; - int* temp = stackalloc int[_Nb]; - - int iNumBlocks = inputCount / _inputBlockSize; - int transformCount = outputOffset; - for (int blockNum = 0; blockNum < iNumBlocks; ++blockNum) - { - fixed (byte* inputPtr = inputBuffer) - { - Buffer.MemoryCopy(inputPtr + workBaseIndex, work, _blockSizeBytes, _blockSizeBytes); - } - - Enc(encryptindex, encryptKeyExpansion, T, TF, work, temp); - - for (int i = 0; i < _Nb; ++i) - { - outputBuffer[transformCount++] = (byte)(temp[i] & 0xFF); - outputBuffer[transformCount++] = (byte)(temp[i] >> 8 & 0xFF); - outputBuffer[transformCount++] = (byte)(temp[i] >> 16 & 0xFF); - outputBuffer[transformCount++] = (byte)(temp[i] >> 24 & 0xFF); - } - workBaseIndex += _inputBlockSize; - } - } - } - } - } - - return inputCount; - } - - - [System.Security.SecuritySafeCritical] // auto-generated - private unsafe int DecryptData(IReadOnlyList inputBuffer, - int inputOffset, - int inputCount, - ref byte[] outputBuffer, - int outputOffset, - bool fLast) - { - if (inputBuffer.Count < inputOffset + inputCount) - throw new CryptographicException("Cryptography_InsufficientBuffer"); - - if (outputBuffer == null) - { - outputBuffer = new byte[inputCount]; - outputOffset = 0; - } - else - { - if ((outputBuffer.Length - outputOffset) < inputCount) - throw new CryptographicException("Cryptography_InsufficientBuffer"); - } - - fixed (int* encryptindex = _encryptindex) - { - fixed (int* encryptKeyExpansion = _encryptKeyExpansion) - { - fixed (int* decryptindex = _decryptindex) - { - fixed (int* decryptKeyExpansion = _decryptKeyExpansion) - { - fixed (int* T = s_T) - { - fixed (int* TF = s_TF) - { - fixed (int* iT = s_iT) - { - fixed (int* iTF = s_iTF) - { - int* work = stackalloc int[_Nb]; - int* temp = stackalloc int[_Nb]; - - int iNumBlocks = inputCount / _inputBlockSize; - int workBaseIndex = inputOffset, index = 0, transformCount = outputOffset; - for (int blockNum = 0; blockNum < iNumBlocks; ++blockNum) - { - index = workBaseIndex; - for (int i = 0; i < _Nb; ++i) - { - int i0 = inputBuffer[index++]; - int i1 = inputBuffer[index++]; - int i2 = inputBuffer[index++]; - int i3 = inputBuffer[index++]; - work[i] = i3 << 24 | i2 << 16 | i1 << 8 | i0; - } - Dec(decryptindex, decryptKeyExpansion, iT, iTF, work, temp); - for (int i = 0; i < _Nb; ++i) - { - outputBuffer[transformCount++] = (byte)(temp[i] & 0xFF); - outputBuffer[transformCount++] = (byte)(temp[i] >> 8 & 0xFF); - outputBuffer[transformCount++] = (byte)(temp[i] >> 16 & 0xFF); - outputBuffer[transformCount++] = (byte)(temp[i] >> 24 & 0xFF); - } - workBaseIndex += _inputBlockSize; - } - if (fLast == false) - return inputCount; - return outputBuffer.Length; - } - } - } - } - } - } - } - } - } - - // - // AES encryption function. - // - [System.Security.SecurityCritical] // auto-generated - private unsafe void Enc(int* encryptindex, int* encryptKeyExpansion, int* T, int* TF, int* work, int* temp) - { - for (int i = 0; i < _Nb; ++i) - { - work[i] ^= encryptKeyExpansion[i]; - } - - int* _encryptindex; - int* _encryptKeyExpansion = &encryptKeyExpansion[_Nb]; - for (int r = 1; r < _Nr; ++r) - { - _encryptindex = encryptindex; - for (int i = 0; i < _Nb; ++i) - { - temp[i] = T[0 + (work[i] & 0xFF)] ^ - T[256 + ((work[_encryptindex[0]] >> 8) & 0xFF)] ^ - T[512 + ((work[_encryptindex[_Nb]] >> 16) & 0xFF)] ^ - T[768 + ((work[_encryptindex[_Nb * 2]] >> 24) & 0xFF)] ^ - *_encryptKeyExpansion; - _encryptindex++; - _encryptKeyExpansion++; - } - - for (int i = 0; i < _Nb; ++i) - { - work[i] = temp[i]; - } - } - - _encryptindex = encryptindex; - for (int i = 0; i < _Nb; ++i) - { - temp[i] = TF[0 + (work[i] & 0xFF)] ^ - TF[256 + ((work[_encryptindex[0]] >> 8) & 0xFF)] ^ - TF[512 + ((work[_encryptindex[_Nb]] >> 16) & 0xFF)] ^ - TF[768 + ((work[_encryptindex[_Nb * 2]] >> 24) & 0xFF)] ^ - *_encryptKeyExpansion; - _encryptindex++; - _encryptKeyExpansion++; - } - } - - // - // AES decryption function. - // - [System.Security.SecurityCritical] // auto-generated - unsafe private void Dec(int* decryptindex, int* decryptKeyExpansion, int* iT, int* iTF, int* work, int* temp) - { - int keyIndex = _Nb * _Nr; - for (int i = 0; i < _Nb; ++i) - { - work[i] ^= decryptKeyExpansion[keyIndex]; - keyIndex++; - } - - int* _decryptindex; - int* _decryptKeyExpansion; - for (int r = 1; r < _Nr; ++r) - { - keyIndex -= 2 * _Nb; - _decryptindex = decryptindex; - _decryptKeyExpansion = &decryptKeyExpansion[keyIndex]; - for (int i = 0; i < _Nb; ++i) - { - temp[i] = iT[0 + ((work[i]) & 0xFF)] ^ - iT[256 + ((work[_decryptindex[0]] >> 8) & 0xFF)] ^ - iT[512 + ((work[_decryptindex[_Nb]] >> 16) & 0xFF)] ^ - iT[768 + ((work[_decryptindex[_Nb * 2]] >> 24) & 0xFF)] ^ - *_decryptKeyExpansion; - keyIndex++; - _decryptindex++; - _decryptKeyExpansion++; - } - for (int i = 0; i < _Nb; ++i) - { - work[i] = temp[i]; - } - } - - keyIndex = 0; - _decryptindex = decryptindex; - _decryptKeyExpansion = &decryptKeyExpansion[keyIndex]; - for (int i = 0; i < _Nb; ++i) - { - temp[i] = iTF[0 + ((work[i]) & 0xFF)] ^ - iTF[256 + ((work[_decryptindex[0]] >> 8) & 0xFF)] ^ - iTF[512 + ((work[_decryptindex[_Nb]] >> 16) & 0xFF)] ^ - iTF[768 + ((work[_decryptindex[_Nb * 2]] >> 24) & 0xFF)] ^ - *_decryptKeyExpansion; - _decryptindex++; - _decryptKeyExpansion++; - } - } - - // - // Key expansion routine. - // - - private void GenerateKeyExpansion(byte[] rgbKey) - { - switch (_blockSizeBits > rgbKey.Length * 8 ? _blockSizeBits : rgbKey.Length * 8) - { - case 128: - _Nr = 10; - break; - default: - throw new CryptographicException("InvalidKeySize"); - } - - _encryptKeyExpansion = new int[_Nb * (_Nr + 1)]; - _decryptKeyExpansion = new int[_Nb * (_Nr + 1)]; - int iTemp; - - int index = 0; - for (int i = 0; i < _Nk; ++i) - { - int i0 = rgbKey[index++]; - int i1 = rgbKey[index++]; - int i2 = rgbKey[index++]; - int i3 = rgbKey[index++]; - _encryptKeyExpansion[i] = i3 << 24 | i2 << 16 | i1 << 8 | i0; - } - - for (int i = _Nk; i < _Nb * (_Nr + 1); ++i) - { - iTemp = _encryptKeyExpansion[i - 1]; - - if (i % _Nk == 0) - { - iTemp = SubWord(rot3(iTemp)); - iTemp = iTemp ^ s_Rcon[(i / _Nk) - 1]; - } - else if (i % _Nk == 4) - { - iTemp = SubWord(iTemp); - } - - _encryptKeyExpansion[i] = _encryptKeyExpansion[i - _Nk] ^ iTemp; - } - - for (int i = 0; i < _Nb; ++i) - { - _decryptKeyExpansion[i] = _encryptKeyExpansion[i]; - _decryptKeyExpansion[_Nb * _Nr + i] = _encryptKeyExpansion[_Nb * _Nr + i]; - } - - for (int i = _Nb; i < _Nb * _Nr; ++i) - { - int key = _encryptKeyExpansion[i]; - int mul02 = MulX(key); - int mul04 = MulX(mul02); - int mul08 = MulX(mul04); - int mul09 = key ^ mul08; - _decryptKeyExpansion[i] = mul02 ^ mul04 ^ mul08 ^ rot3(mul02 ^ mul09) ^ rot2(mul04 ^ mul09) ^ rot1(mul09); - } - } - - private static int rot1(int val) - { - return (val << 8 & unchecked((int)0xFFFFFF00)) | (val >> 24 & unchecked((int)0x000000FF)); - } - - private static int rot2(int val) - { - return (val << 16 & unchecked((int)0xFFFF0000)) | (val >> 16 & unchecked((int)0x0000FFFF)); - } - - private static int rot3(int val) - { - return (val << 24 & unchecked((int)0xFF000000)) | (val >> 8 & unchecked((int)0x00FFFFFF)); - } - - private static int SubWord(int a) - { - return s_Sbox[a & 0xFF] | - s_Sbox[a >> 8 & 0xFF] << 8 | - s_Sbox[a >> 16 & 0xFF] << 16 | - s_Sbox[a >> 24 & 0xFF] << 24; - } - - private static int MulX(int x) - { - int u = x & unchecked((int)0x80808080); - return ((x & unchecked((int)0x7f7f7f7f)) << 1) ^ ((u - (u >> 7 & 0x01FFFFFF)) & 0x1b1b1b1b); - } - - private static readonly byte[] s_Sbox = new byte[] { - 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, - 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, - 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, - 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, - 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, - 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, - 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, - 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, - 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, - 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, - 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, - 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, - 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, - 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, - 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, - 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22 }; - - private static readonly int[] s_Rcon = new int[] { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, - 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, - 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 }; - - private static readonly int[] s_T = new int[4 * 256] - { - // s_T1 - -1520213050, -2072216328, -1720223762, -1921287178, 234025727, -1117033514, -1318096930, 1422247313, - 1345335392, 50397442, -1452841010, 2099981142, 436141799, 1658312629, -424957107, -1703512340, - 1170918031, -1652391393, 1086966153, -2021818886, 368769775, -346465870, -918075506, 200339707, - -324162239, 1742001331, -39673249, -357585083, -1080255453, -140204973, -1770884380, 1539358875, - -1028147339, 486407649, -1366060227, 1780885068, 1513502316, 1094664062, 49805301, 1338821763, - 1546925160, -190470831, 887481809, 150073849, -1821281822, 1943591083, 1395732834, 1058346282, - 201589768, 1388824469, 1696801606, 1589887901, 672667696, -1583966665, 251987210, -1248159185, - 151455502, 907153956, -1686077413, 1038279391, 652995533, 1764173646, -843926913, -1619692054, - 453576978, -1635548387, 1949051992, 773462580, 756751158, -1301385508, -296068428, -73359269, - -162377052, 1295727478, 1641469623, -827083907, 2066295122, 1055122397, 1898917726, -1752923117, - -179088474, 1758581177, 0, 753790401, 1612718144, 536673507, -927878791, -312779850, - -1100322092, 1187761037, -641810841, 1262041458, -565556588, -733197160, -396863312, 1255133061, - 1808847035, 720367557, -441800113, 385612781, -985447546, -682799718, 1429418854, -1803188975, - -817543798, 284817897, 100794884, -2122350594, -263171936, 1144798328, -1163944155, -475486133, - -212774494, -22830243, -1069531008, -1970303227, -1382903233, -1130521311, 1211644016, 83228145, - -541279133, -1044990345, 1977277103, 1663115586, 806359072, 452984805, 250868733, 1842533055, - 1288555905, 336333848, 890442534, 804056259, -513843266, -1567123659, -867941240, 957814574, - 1472513171, -223893675, -2105639172, 1195195770, -1402706744, -413311558, 723065138, -1787595802, - -1604296512, -1736343271, -783331426, 2145180835, 1713513028, 2116692564, -1416589253, -2088204277, - -901364084, 703524551, -742868885, 1007948840, 2044649127, -497131844, 487262998, 1994120109, - 1004593371, 1446130276, 1312438900, 503974420, -615954030, 168166924, 1814307912, -463709000, - 1573044895, 1859376061, -273896381, -1503501628, -1466855111, -1533700815, 937747667, -1954973198, - 854058965, 1137232011, 1496790894, -1217565222, -1936880383, 1691735473, -766620004, -525751991, - -1267962664, -95005012, 133494003, 636152527, -1352309302, -1904575756, -374428089, 403179536, - -709182865, -2005370640, 1864705354, 1915629148, 605822008, -240736681, -944458637, 1371981463, - 602466507, 2094914977, -1670089496, 555687742, -582268010, -591544991, -2037675251, -2054518257, - -1871679264, 1111375484, -994724495, -1436129588, -666351472, 84083462, 32962295, 302911004, - -1553899070, 1597322602, -111716434, -793134743, -1853454825, 1489093017, 656219450, -1180787161, - 954327513, 335083755, -1281845205, 856756514, -1150719534, 1893325225, -1987146233, -1483434957, - -1231316179, 572399164, -1836611819, 552200649, 1238290055, -11184726, 2015897680, 2061492133, - -1886614525, -123625127, -2138470135, 386731290, -624967835, 837215959, -968736124, -1201116976, - -1019133566, -1332111063, 1999449434, 286199582, -877612933, -61582168, -692339859, 974525996, - - // s_T2 - 1667483301, 2088564868, 2004348569, 2071721613, -218956019, 1802229437, 1869602481, -976907948, - 808476752, 16843267, 1734856361, 724260477, -16849127, -673729182, -1414836762, 1987505306, - -892694715, -2105401443, -909539008, 2105408135, -84218091, 1499050731, 1195871945, -252642549, - -1381154324, -724257945, -1566416899, -1347467798, -1667488833, -1532734473, 1920132246, -1061119141, - -1212713534, -33693412, -1819066962, 640044138, 909536346, 1061125697, -134744830, -859012273, - 875849820, -1515892236, -437923532, -235800312, 1903288979, -656888973, 825320019, 353708607, - 67373068, -943221422, 589514341, -1010590370, 404238376, -1768540255, 84216335, -1701171275, - 117902857, 303178806, -2139087973, -488448195, -336868058, 656887401, -1296924723, 1970662047, - 151589403, -2088559202, 741103732, 437924910, 454768173, 1852759218, 1515893998, -1600103429, - 1381147894, 993752653, -690571423, -1280082482, 690573947, -471605954, 791633521, -2071719017, - 1397991157, -774784664, 0, -303185620, 538984544, -50535649, -1313769016, 1532737261, - 1785386174, -875852474, -1094817831, 960066123, 1246401758, 1280088276, 1482207464, -808483510, - -791626901, -269499094, -1431679003, -67375850, 1128498885, 1296931543, 859006549, -2054876780, - 1162185423, -101062384, 33686534, 2139094657, 1347461360, 1010595908, -1616960070, -1465365533, - 1364304627, -1549574658, 1077969088, -1886452342, -1835909203, -1650646596, 943222856, -168431356, - -1128504353, -1229555775, -623202443, 555827811, 269492272, -6886, -202113778, -757940371, - -842170036, 202119188, 320022069, -320027857, 1600110305, -1751698014, 1145342156, 387395129, - -993750185, -1482205710, 2122251394, 1027439175, 1684326572, 1566423783, 421081643, 1936975509, - 1616953504, -2122245736, 1330618065, -589520001, 572671078, 707417214, -1869595733, -2004350077, - 1179028682, -286341335, -1195873325, 336865340, -555833479, 1583267042, 185275933, -606360202, - -522134725, 842163286, 976909390, 168432670, 1229558491, 101059594, 606357612, 1549580516, - -1027432611, -741098130, -1397996561, 1650640038, -1852753496, -1785384540, -454765769, 2038035083, - -404237006, -926381245, 926379609, 1835915959, -1920138868, -707415708, 1313774802, -1448523296, - 1819072692, 1448520954, -185273593, -353710299, 1701169839, 2054878350, -1364310039, 134746136, - -1162186795, 2021191816, 623200879, 774790258, 471611428, -1499047951, -1263242297, -960063663, - -387396829, -572677764, 1953818780, 522141217, 1263245021, -1111662116, -1953821306, -1970663547, - 1886445712, 1044282434, -1246400060, 1718013098, 1212715224, 50529797, -151587071, 235805714, - 1633796771, 892693087, 1465364217, -1179031088, -2038032495, -1044276904, 488454695, -1633802311, - -505292488, -117904621, -1734857805, 286335539, 1768542907, -640046736, -1903294583, -1802226777, - -1684329034, 505297954, -2021190254, -370554592, -825325751, 1431677695, 673730680, -538991238, - -1936981105, -1583261192, -1987507840, 218962455, -1077975590, -421079247, 1111655622, 1751699640, - 1094812355, -1718015568, 757946999, 252648977, -1330611253, 1414834428, -1145344554, 370551866, - - // s_T3 - 1673962851, 2096661628, 2012125559, 2079755643, -218165774, 1809235307, 1876865391, -980331323, - 811618352, 16909057, 1741597031, 727088427, -18408962, -675978537, -1420958037, 1995217526, - -896580150, -2111857278, -913751863, 2113570685, -84994566, 1504897881, 1200539975, -251982864, - -1388188499, -726439980, -1570767454, -1354372433, -1675378788, -1538000988, 1927583346, -1063560256, - -1217019209, -35578627, -1824674157, 642542118, 913070646, 1065238847, -134937865, -863809588, - 879254580, -1521355611, -439274267, -235337487, 1910674289, -659852328, 828527409, 355090197, - 67636228, -946515257, 591815971, -1013096765, 405809176, -1774739050, 84545285, -1708149350, - 118360327, 304363026, -2145674368, -488686110, -338876693, 659450151, -1300247118, 1978310517, - 152181513, -2095210877, 743994412, 439627290, 456535323, 1859957358, 1521806938, -1604584544, - 1386542674, 997608763, -692624938, -1283600717, 693271337, -472039709, 794718511, -2079090812, - 1403450707, -776378159, 0, -306107155, 541089824, -52224004, -1317418831, 1538714971, - 1792327274, -879933749, -1100490306, 963791673, 1251270218, 1285084236, 1487988824, -813348145, - -793023536, -272291089, -1437604438, -68348165, 1132905795, 1301993293, 862344499, -2062445435, - 1166724933, -102166279, 33818114, 2147385727, 1352724560, 1014514748, -1624917345, -1471421528, - 1369633617, -1554121053, 1082179648, -1895462257, -1841320558, -1658733411, 946882616, -168753931, - -1134305348, -1233665610, -626035238, 557998881, 270544912, -1762561, -201519373, -759206446, - -847164211, 202904588, 321271059, -322752532, 1606345055, -1758092649, 1149815876, 388905239, - -996976700, -1487539545, 2130477694, 1031423805, 1690872932, 1572530013, 422718233, 1944491379, - 1623236704, -2129028991, 1335808335, -593264676, 574907938, 710180394, -1875137648, -2012511352, - 1183631942, -288937490, -1200893000, 338181140, -559449634, 1589437022, 185998603, -609388837, - -522503200, 845436466, 980700730, 169090570, 1234361161, 101452294, 608726052, 1555620956, - -1029743166, -742560045, -1404833876, 1657054818, -1858492271, -1791908715, -455919644, 2045938553, - -405458201, -930397240, 929978679, 1843050349, -1929278323, -709794603, 1318900302, -1454776151, - 1826141292, 1454176854, -185399308, -355523094, 1707781989, 2062847610, -1371018834, 135272456, - -1167075910, 2029029496, 625635109, 777810478, 473441308, -1504185946, -1267480652, -963161658, - -389340184, -576619299, 1961401460, 524165407, 1268178251, -1117659971, -1962047861, -1978694262, - 1893765232, 1048330814, -1250835275, 1724688998, 1217452104, 50726147, -151584266, 236720654, - 1640145761, 896163637, 1471084887, -1184247623, -2045275770, -1046914879, 490350365, -1641563746, - -505857823, -118811656, -1741966440, 287453969, 1775418217, -643206951, -1912108658, -1808554092, - -1691502949, 507257374, -2028629369, -372694807, -829994546, 1437269845, 676362280, -542803233, - -1945923700, -1587939167, -1995865975, 219813645, -1083843905, -422104602, 1115997762, 1758509160, - 1099088705, -1725321063, 760903469, 253628687, -1334064208, 1420360788, -1150429509, 371997206, - - // s_T4 - -962239645, -125535108, -291932297, -158499973, -15863054, -692229269, -558796945, -1856715323, - 1615867952, 33751297, -827758745, 1451043627, -417726722, -1251813417, 1306962859, -325421450, - -1891251510, 530416258, -1992242743, -91783811, -283772166, -1293199015, -1899411641, -83103504, - 1106029997, -1285040940, 1610457762, 1173008303, 599760028, 1408738468, -459902350, -1688485696, - 1975695287, -518193667, 1034851219, 1282024998, 1817851446, 2118205247, -184354825, -2091922228, - 1750873140, 1374987685, -785062427, -116854287, -493653647, -1418471208, 1649619249, 708777237, - 135005188, -1789737017, 1181033251, -1654733885, 807933976, 933336726, 168756485, 800430746, - 235472647, 607523346, 463175808, -549592350, -853087253, 1315514151, 2144187058, -358648459, - 303761673, 496927619, 1484008492, 875436570, 908925723, -592286098, -1259447718, 1543217312, - -1527360942, 1984772923, -1218324778, 2110698419, 1383803177, -583080989, 1584475951, 328696964, - -1493871789, -1184312879, 0, -1054020115, 1080041504, -484442884, 2043195825, -1225958565, - -725718422, -1924740149, 1742323390, 1917532473, -1797371318, -1730917300, -1326950312, -2058694705, - -1150562096, -987041809, 1340451498, -317260805, -2033892541, -1697166003, 1716859699, 294946181, - -1966127803, -384763399, 67502594, -25067649, -1594863536, 2017737788, 632987551, 1273211048, - -1561112239, 1576969123, -2134884288, 92966799, 1068339858, 566009245, 1883781176, -251333131, - 1675607228, 2009183926, -1351230758, 1113792801, 540020752, -451215361, -49351693, -1083321646, - -2125673011, 403966988, 641012499, -1020269332, -1092526241, 899848087, -1999879100, 775493399, - -1822964540, 1441965991, -58556802, 2051489085, -928226204, -1159242403, 841685273, -426413197, - -1063231392, 429425025, -1630449841, -1551901476, 1147544098, 1417554474, 1001099408, 193169544, - -1932900794, -953553170, 1809037496, 675025940, -1485185314, -1126015394, 371002123, -1384719397, - -616832800, 1683370546, 1951283770, 337512970, -1831122615, 201983494, 1215046692, -1192993700, - -1621245246, -1116810285, 1139780780, -995728798, 967348625, 832869781, -751311644, -225740423, - -718084121, -1958491960, 1851340599, -625513107, 25988493, -1318791723, -1663938994, 1239460265, - -659264404, -1392880042, -217582348, -819598614, -894474907, -191989126, 1206496942, 270010376, - 1876277946, -259491720, 1248797989, 1550986798, 941890588, 1475454630, 1942467764, -1756248378, - -886839064, -1585652259, -392399756, 1042358047, -1763882165, 1641856445, 226921355, 260409994, - -527404944, 2084716094, 1908716981, -861247898, -1864873912, 100991747, -150866186, 470945294, - -1029480095, 1784624437, -1359390889, 1775286713, 395413126, -1722236479, 975641885, 666476190, - -650583583, -351012616, 733190296, 573772049, -759469719, -1452221991, 126455438, 866620564, - 766942107, 1008868894, 361924487, -920589847, -2025206066, -1426107051, 1350051880, -1518673953, - 59739276, 1509466529, 159418761, 437718285, 1708834751, -684595482, -2067381694, -793221016, - -2101132991, 699439513, 1517759789, 504434447, 2076946608, -1459858348, 1842789307, 742004246 }; - - private static readonly int[] s_TF = new int[4 * 256] - { - // s_TF1 - 99, 124, 119, 123, 242, 107, 111, 197, - 48, 1, 103, 43, 254, 215, 171, 118, - 202, 130, 201, 125, 250, 89, 71, 240, - 173, 212, 162, 175, 156, 164, 114, 192, - 183, 253, 147, 38, 54, 63, 247, 204, - 52, 165, 229, 241, 113, 216, 49, 21, - 4, 199, 35, 195, 24, 150, 5, 154, - 7, 18, 128, 226, 235, 39, 178, 117, - 9, 131, 44, 26, 27, 110, 90, 160, - 82, 59, 214, 179, 41, 227, 47, 132, - 83, 209, 0, 237, 32, 252, 177, 91, - 106, 203, 190, 57, 74, 76, 88, 207, - 208, 239, 170, 251, 67, 77, 51, 133, - 69, 249, 2, 127, 80, 60, 159, 168, - 81, 163, 64, 143, 146, 157, 56, 245, - 188, 182, 218, 33, 16, 255, 243, 210, - 205, 12, 19, 236, 95, 151, 68, 23, - 196, 167, 126, 61, 100, 93, 25, 115, - 96, 129, 79, 220, 34, 42, 144, 136, - 70, 238, 184, 20, 222, 94, 11, 219, - 224, 50, 58, 10, 73, 6, 36, 92, - 194, 211, 172, 98, 145, 149, 228, 121, - 231, 200, 55, 109, 141, 213, 78, 169, - 108, 86, 244, 234, 101, 122, 174, 8, - 186, 120, 37, 46, 28, 166, 180, 198, - 232, 221, 116, 31, 75, 189, 139, 138, - 112, 62, 181, 102, 72, 3, 246, 14, - 97, 53, 87, 185, 134, 193, 29, 158, - 225, 248, 152, 17, 105, 217, 142, 148, - 155, 30, 135, 233, 206, 85, 40, 223, - 140, 161, 137, 13, 191, 230, 66, 104, - 65, 153, 45, 15, 176, 84, 187, 22, - - // s_TF2 - 25344, 31744, 30464, 31488, 61952, 27392, 28416, 50432, - 12288, 256, 26368, 11008, 65024, 55040, 43776, 30208, - 51712, 33280, 51456, 32000, 64000, 22784, 18176, 61440, - 44288, 54272, 41472, 44800, 39936, 41984, 29184, 49152, - 46848, 64768, 37632, 9728, 13824, 16128, 63232, 52224, - 13312, 42240, 58624, 61696, 28928, 55296, 12544, 5376, - 1024, 50944, 8960, 49920, 6144, 38400, 1280, 39424, - 1792, 4608, 32768, 57856, 60160, 9984, 45568, 29952, - 2304, 33536, 11264, 6656, 6912, 28160, 23040, 40960, - 20992, 15104, 54784, 45824, 10496, 58112, 12032, 33792, - 21248, 53504, 0, 60672, 8192, 64512, 45312, 23296, - 27136, 51968, 48640, 14592, 18944, 19456, 22528, 52992, - 53248, 61184, 43520, 64256, 17152, 19712, 13056, 34048, - 17664, 63744, 512, 32512, 20480, 15360, 40704, 43008, - 20736, 41728, 16384, 36608, 37376, 40192, 14336, 62720, - 48128, 46592, 55808, 8448, 4096, 65280, 62208, 53760, - 52480, 3072, 4864, 60416, 24320, 38656, 17408, 5888, - 50176, 42752, 32256, 15616, 25600, 23808, 6400, 29440, - 24576, 33024, 20224, 56320, 8704, 10752, 36864, 34816, - 17920, 60928, 47104, 5120, 56832, 24064, 2816, 56064, - 57344, 12800, 14848, 2560, 18688, 1536, 9216, 23552, - 49664, 54016, 44032, 25088, 37120, 38144, 58368, 30976, - 59136, 51200, 14080, 27904, 36096, 54528, 19968, 43264, - 27648, 22016, 62464, 59904, 25856, 31232, 44544, 2048, - 47616, 30720, 9472, 11776, 7168, 42496, 46080, 50688, - 59392, 56576, 29696, 7936, 19200, 48384, 35584, 35328, - 28672, 15872, 46336, 26112, 18432, 768, 62976, 3584, - 24832, 13568, 22272, 47360, 34304, 49408, 7424, 40448, - 57600, 63488, 38912, 4352, 26880, 55552, 36352, 37888, - 39680, 7680, 34560, 59648, 52736, 21760, 10240, 57088, - 35840, 41216, 35072, 3328, 48896, 58880, 16896, 26624, - 16640, 39168, 11520, 3840, 45056, 21504, 47872, 5632, - - // s_TF3 - 6488064, 8126464, 7798784, 8060928, 15859712, 7012352, 7274496, 12910592, - 3145728, 65536, 6750208, 2818048, 16646144, 14090240, 11206656, 7733248, - 13238272, 8519680, 13172736, 8192000, 16384000, 5832704, 4653056, 15728640, - 11337728, 13893632, 10616832, 11468800, 10223616, 10747904, 7471104, 12582912, - 11993088, 16580608, 9633792, 2490368, 3538944, 4128768, 16187392, 13369344, - 3407872, 10813440, 15007744, 15794176, 7405568, 14155776, 3211264, 1376256, - 262144, 13041664, 2293760, 12779520, 1572864, 9830400, 327680, 10092544, - 458752, 1179648, 8388608, 14811136, 15400960, 2555904, 11665408, 7667712, - 589824, 8585216, 2883584, 1703936, 1769472, 7208960, 5898240, 10485760, - 5373952, 3866624, 14024704, 11730944, 2686976, 14876672, 3080192, 8650752, - 5439488, 13697024, 0, 15532032, 2097152, 16515072, 11599872, 5963776, - 6946816, 13303808, 12451840, 3735552, 4849664, 4980736, 5767168, 13565952, - 13631488, 15663104, 11141120, 16449536, 4390912, 5046272, 3342336, 8716288, - 4521984, 16318464, 131072, 8323072, 5242880, 3932160, 10420224, 11010048, - 5308416, 10682368, 4194304, 9371648, 9568256, 10289152, 3670016, 16056320, - 12320768, 11927552, 14286848, 2162688, 1048576, 16711680, 15925248, 13762560, - 13434880, 786432, 1245184, 15466496, 6225920, 9895936, 4456448, 1507328, - 12845056, 10944512, 8257536, 3997696, 6553600, 6094848, 1638400, 7536640, - 6291456, 8454144, 5177344, 14417920, 2228224, 2752512, 9437184, 8912896, - 4587520, 15597568, 12058624, 1310720, 14548992, 6160384, 720896, 14352384, - 14680064, 3276800, 3801088, 655360, 4784128, 393216, 2359296, 6029312, - 12713984, 13828096, 11272192, 6422528, 9502720, 9764864, 14942208, 7929856, - 15138816, 13107200, 3604480, 7143424, 9240576, 13959168, 5111808, 11075584, - 7077888, 5636096, 15990784, 15335424, 6619136, 7995392, 11403264, 524288, - 12189696, 7864320, 2424832, 3014656, 1835008, 10878976, 11796480, 12976128, - 15204352, 14483456, 7602176, 2031616, 4915200, 12386304, 9109504, 9043968, - 7340032, 4063232, 11862016, 6684672, 4718592, 196608, 16121856, 917504, - 6356992, 3473408, 5701632, 12124160, 8781824, 12648448, 1900544, 10354688, - 14745600, 16252928, 9961472, 1114112, 6881280, 14221312, 9306112, 9699328, - 10158080, 1966080, 8847360, 15269888, 13500416, 5570560, 2621440, 14614528, - 9175040, 10551296, 8978432, 851968, 12517376, 15073280, 4325376, 6815744, - 4259840, 10027008, 2949120, 983040, 11534336, 5505024, 12255232, 1441792, - - // s_TF4 - 1660944384, 2080374784, 1996488704, 2063597568, -234881024, 1795162112, 1862270976, -989855744, - 805306368, 16777216, 1728053248, 721420288, -33554432, -687865856, -1426063360, 1979711488, - -905969664, -2113929216, -922746880, 2097152000, -100663296, 1493172224, 1191182336, -268435456, - -1392508928, -738197504, -1577058304, -1358954496, -1677721600, -1543503872, 1912602624, -1073741824, - -1224736768, -50331648, -1828716544, 637534208, 905969664, 1056964608, -150994944, -872415232, - 872415232, -1526726656, -452984832, -251658240, 1895825408, -671088640, 822083584, 352321536, - 67108864, -956301312, 587202560, -1023410176, 402653184, -1778384896, 83886080, -1711276032, - 117440512, 301989888, -2147483648, -503316480, -352321536, 654311424, -1308622848, 1962934272, - 150994944, -2097152000, 738197504, 436207616, 452984832, 1845493760, 1509949440, -1610612736, - 1375731712, 989855744, -704643072, -1291845632, 687865856, -486539264, 788529152, -2080374784, - 1392508928, -788529152, 0, -318767104, 536870912, -67108864, -1325400064, 1526726656, - 1778384896, -889192448, -1107296256, 956301312, 1241513984, 1275068416, 1476395008, -822083584, - -805306368, -285212672, -1442840576, -83886080, 1124073472, 1291845632, 855638016, -2063597568, - 1157627904, -117440512, 33554432, 2130706432, 1342177280, 1006632960, -1627389952, -1476395008, - 1358954496, -1560281088, 1073741824, -1895825408, -1845493760, -1660944384, 939524096, -184549376, - -1140850688, -1241513984, -637534208, 553648128, 268435456, -16777216, -218103808, -771751936, - -855638016, 201326592, 318767104, -335544320, 1593835520, -1761607680, 1140850688, 385875968, - -1006632960, -1493172224, 2113929216, 1023410176, 1677721600, 1560281088, 419430400, 1929379840, - 1610612736, -2130706432, 1325400064, -603979776, 570425344, 704643072, -1879048192, -2013265920, - 1174405120, -301989888, -1207959552, 335544320, -570425344, 1577058304, 184549376, -620756992, - -536870912, 838860800, 973078528, 167772160, 1224736768, 100663296, 603979776, 1543503872, - -1040187392, -754974720, -1409286144, 1644167168, -1862270976, -1795162112, -469762048, 2030043136, - -419430400, -939524096, 922746880, 1828716544, -1929379840, -721420288, 1308622848, -1459617792, - 1811939328, 1442840576, -201326592, -369098752, 1694498816, 2046820352, -1375731712, 134217728, - -1174405120, 2013265920, 620756992, 771751936, 469762048, -1509949440, -1275068416, -973078528, - -402653184, -587202560, 1946157056, 520093696, 1258291200, -1124073472, -1962934272, -1979711488, - 1879048192, 1040187392, -1258291200, 1711276032, 1207959552, 50331648, -167772160, 234881024, - 1627389952, 889192448, 1459617792, -1191182336, -2046820352, -1056964608, 486539264, -1644167168, - -520093696, -134217728, -1744830464, 285212672, 1761607680, -654311424, -1912602624, -1811939328, - -1694498816, 503316480, -2030043136, -385875968, -838860800, 1426063360, 671088640, -553648128, - -1946157056, -1593835520, -1996488704, 218103808, -1090519040, -436207616, 1107296256, 1744830464, - 1090519040, -1728053248, 754974720, 251658240, -1342177280, 1409286144, -1157627904, 369098752 }; - - private static readonly int[] s_iT = new int[4 * 256] - { - // s_iT1 - 1353184337, 1399144830, -1012656358, -1772214470, -882136261, -247096033, -1420232020, -1828461749, - 1442459680, -160598355, -1854485368, 625738485, -52959921, -674551099, -2143013594, -1885117771, - 1230680542, 1729870373, -1743852987, -507445667, 41234371, 317738113, -1550367091, -956705941, - -413167869, -1784901099, -344298049, -631680363, 763608788, -752782248, 694804553, 1154009486, - 1787413109, 2021232372, 1799248025, -579749593, -1236278850, 397248752, 1722556617, -1271214467, - 407560035, -2110711067, 1613975959, 1165972322, -529046351, -2068943941, 480281086, -1809118983, - 1483229296, 436028815, -2022908268, -1208452270, 601060267, -503166094, 1468997603, 715871590, - 120122290, 63092015, -1703164538, -1526188077, -226023376, -1297760477, -1167457534, 1552029421, - 723308426, -1833666137, -252573709, -1578997426, -839591323, -708967162, 526529745, -1963022652, - -1655493068, -1604979806, 853641733, 1978398372, 971801355, -1427152832, 111112542, 1360031421, - -108388034, 1023860118, -1375387939, 1186850381, -1249028975, 90031217, 1876166148, -15380384, - 620468249, -1746289194, -868007799, 2006899047, -1119688528, -2004121337, 945494503, -605108103, - 1191869601, -384875908, -920746760, 0, -2088337399, 1223502642, -1401941730, 1316117100, - -67170563, 1446544655, 517320253, 658058550, 1691946762, 564550760, -783000677, 976107044, - -1318647284, 266819475, -761860428, -1634624741, 1338359936, -1574904735, 1766553434, 370807324, - 179999714, -450191168, 1138762300, 488053522, 185403662, -1379431438, -1180125651, -928440812, - -2061897385, 1275557295, -1143105042, -44007517, -1624899081, -1124765092, -985962940, 880737115, - 1982415755, -590994485, 1761406390, 1676797112, -891538985, 277177154, 1076008723, 538035844, - 2099530373, -130171950, 288553390, 1839278535, 1261411869, -214912292, -330136051, -790380169, - 1813426987, -1715900247, -95906799, 577038663, -997393240, 440397984, -668172970, -275762398, - -951170681, -1043253031, -22885748, 906744984, -813566554, 685669029, 646887386, -1530942145, - -459458004, 227702864, -1681105046, 1648787028, -1038905866, -390539120, 1593260334, -173030526, - -1098883681, 2090061929, -1456614033, -1290656305, 999926984, -1484974064, 1852021992, 2075868123, - 158869197, -199730834, 28809964, -1466282109, 1701746150, 2129067946, 147831841, -420997649, - -644094022, -835293366, -737566742, -696471511, -1347247055, 824393514, 815048134, -1067015627, - 935087732, -1496677636, -1328508704, 366520115, 1251476721, -136647615, 240176511, 804688151, - -1915335306, 1303441219, 1414376140, -553347356, -474623586, 461924940, -1205916479, 2136040774, - 82468509, 1563790337, 1937016826, 776014843, 1511876531, 1389550482, 861278441, 323475053, - -1939744870, 2047648055, -1911228327, -1992551445, -299390514, 902390199, -303751967, 1018251130, - 1507840668, 1064563285, 2043548696, -1086863501, -355600557, 1537932639, 342834655, -2032450440, - -2114736182, 1053059257, 741614648, 1598071746, 1925389590, 203809468, -1958134744, 1100287487, - 1895934009, -558691320, -1662733096, -1866377628, 1636092795, 1890988757, 1952214088, 1113045200, - - // s_iT2 - -1477160624, 1698790995, -1541989693, 1579629206, 1806384075, 1167925233, 1492823211, 65227667, - -97509291, 1836494326, 1993115793, 1275262245, -672837636, -886389289, 1144333952, -1553812081, - 1521606217, 465184103, 250234264, -1057071647, 1966064386, -263421678, -1756983901, -103584826, - 1603208167, -1668147819, 2054012907, 1498584538, -2084645843, 561273043, 1776306473, -926314940, - -1983744662, 2039411832, 1045993835, 1907959773, 1340194486, -1383534569, -1407137434, 986611124, - 1256153880, 823846274, 860985184, 2136171077, 2003087840, -1368671356, -1602093540, 722008468, - 1749577816, -45773031, 1826526343, -126135625, -747394269, 38499042, -1893735593, -1420466646, - 686535175, -1028313341, 2076542618, 137876389, -2027409166, -1514200142, 1778582202, -2112426660, - 483363371, -1267095662, -234359824, -496415071, -187013683, -1106966827, 1647628575, -22625142, - 1395537053, 1442030240, -511048398, -336157579, -326956231, -278904662, -1619960314, 275692881, - -1977532679, 115185213, 88006062, -1108980410, -1923837515, 1573155077, -737803153, 357589247, - -73918172, -373434729, 1128303052, -1629919369, 1122545853, -1953953912, 1528424248, -288851493, - 175939911, 256015593, 512030921, 0, -2038429309, -315936184, 1880170156, 1918528590, - -15794693, 948244310, -710001378, 959264295, -653325724, -1503893471, 1415289809, 775300154, - 1728711857, -413691121, -1762741038, -1852105826, -977239985, 551313826, 1266113129, 437394454, - -1164713462, 715178213, -534627261, 387650077, 218697227, -947129683, -1464455751, -1457646392, - 435246981, 125153100, -577114437, 1618977789, 637663135, -177054532, 996558021, 2130402100, - 692292470, -970732580, -51530136, -236668829, -600713270, -2057092592, 580326208, 298222624, - 608863613, 1035719416, 855223825, -1591097491, 798891339, 817028339, 1384517100, -473860144, - 380840812, -1183798887, 1217663482, 1693009698, -1929598780, 1072734234, 746411736, -1875696913, - 1313441735, -784803391, -1563783938, 198481974, -2114607409, -562387672, -1900553690, -1079165020, - -1657131804, -1837608947, -866162021, 1182684258, 328070850, -1193766680, -147247522, -1346141451, - -2141347906, -1815058052, 768962473, 304467891, -1716729797, 2098729127, 1671227502, -1153705093, - 2015808777, 408514292, -1214583807, -1706064984, 1855317605, -419452290, -809754360, -401215514, - -1679312167, 913263310, 161475284, 2091919830, -1297862225, 591342129, -1801075152, 1721906624, - -1135709129, -897385306, -795811664, -660131051, -1744506550, -622050825, 1355644686, -158263505, - -699566451, -1326496947, 1303039060, 76997855, -1244553501, -2006299621, 523026872, 1365591679, - -362898172, 898367837, 1955068531, 1091304238, 493335386, -757362094, 1443948851, 1205234963, - 1641519756, 211892090, 351820174, 1007938441, 665439982, -916342987, -451091987, -1320715716, - -539845543, 1945261375, -837543815, 935818175, -839429142, -1426235557, 1866325780, -616269690, - -206583167, -999769794, 874788908, 1084473951, -1021503886, 635616268, 1228679307, -1794244799, - 27801969, -1291056930, -457910116, -1051302768, -2067039391, -1238182544, 1550600308, 1471729730, - - // s_iT3 - -195997529, 1098797925, 387629988, 658151006, -1422144661, -1658851003, -89347240, -481586429, - 807425530, 1991112301, -863465098, 49620300, -447742761, 717608907, 891715652, 1656065955, - -1310832294, -1171953893, -364537842, -27401792, 801309301, 1283527408, 1183687575, -747911431, - -1895569569, -1844079204, 1841294202, 1385552473, -1093390973, 1951978273, -532076183, -913423160, - -1032492407, -1896580999, 1486449470, -1188569743, -507595185, -1997531219, 550069932, -830622662, - -547153846, 451248689, 1368875059, 1398949247, 1689378935, 1807451310, -2114052960, 150574123, - 1215322216, 1167006205, -560691348, 2069018616, 1940595667, 1265820162, 534992783, 1432758955, - -340654296, -1255210046, -981034373, 936617224, 674296455, -1088179547, 50510442, 384654466, - -813028580, 2041025204, 133427442, 1766760930, -630862348, 84334014, 886120290, -1497068802, - 775200083, -207445931, -1979370783, -156994069, -2096416276, 1614850799, 1901987487, 1857900816, - 557775242, -577356538, 1054715397, -431143235, 1418835341, -999226019, 100954068, 1348534037, - -1743182597, -1110009879, 1082772547, -647530594, -391070398, -1995994997, 434583643, -931537938, - 2090944266, 1115482383, -2064070370, 0, -2146860154, 724715757, 287222896, 1517047410, - 251526143, -2062592456, -1371726123, 758523705, 252339417, 1550328230, 1536938324, 908343854, - 168604007, 1469255655, -290139498, -1692688751, -1065332795, -597581280, 2002413899, 303830554, - -1813902662, -1597971158, 574374880, 454171927, 151915277, -1947030073, -1238517336, 504678569, - -245922535, 1974422535, -1712407587, 2141453664, 33005350, 1918680309, 1715782971, -77908866, - 1133213225, 600562886, -306812676, -457677839, 836225756, 1665273989, -1760346078, -964419567, - 1250262308, -1143801795, -106032846, 700935585, -1642247377, -1294142672, -2045907886, -1049112349, - -1288999914, 1890163129, -1810761144, -381214108, -56048500, -257942977, 2102843436, 857927568, - 1233635150, 953795025, -896729438, -728222197, -173617279, 2057644254, -1210440050, -1388337985, - 976020637, 2018512274, 1600822220, 2119459398, -1913208301, -661591880, 959340279, -1014827601, - 1570750080, -798393197, -714102483, 634368786, -1396163687, 403744637, -1662488989, 1004239803, - 650971512, 1500443672, -1695809097, 1334028442, -1780062866, -5603610, -1138685745, 368043752, - -407184997, 1867173430, -1612000247, -1339435396, -1540247630, 1059729699, -1513738092, -1573535642, - 1316239292, -2097371446, -1864322864, -1489824296, 82922136, -331221030, -847311280, -1860751370, - 1299615190, -280801872, -1429449651, -1763385596, -778116171, 1783372680, 750893087, 1699118929, - 1587348714, -1946067659, -2013629580, 201010753, 1739807261, -611167534, 283718486, -697494713, - -677737375, -1590199796, -128348652, 334203196, -1446056409, 1639396809, 484568549, 1199193265, - -761505313, -229294221, 337148366, -948715721, -145495347, -44082262, 1038029935, 1148749531, - -1345682957, 1756970692, 607661108, -1547542720, 488010435, -490992603, 1009290057, 234832277, - -1472630527, 201907891, -1260872476, 1449431233, -881106556, 852848822, 1816687708, -1194311081, - - // s_iT4 - 1364240372, 2119394625, 449029143, 982933031, 1003187115, 535905693, -1398056710, 1267925987, - 542505520, -1376359050, -2003732788, -182105086, 1341970405, -975713494, 645940277, -1248877726, - -565617999, 627514298, 1167593194, 1575076094, -1023249105, -2129465268, -1918658746, 1808202195, - 65494927, 362126482, -1075086739, -1780852398, -735214658, 1490231668, 1227450848, -1908094775, - 1969916354, -193431154, -1721024936, 668823993, -1095348255, -266883704, -916018144, 2108963534, - 1662536415, -444452582, -1755303087, 1648721747, -1310689436, -1148932501, -31678335, -107730168, - 1884842056, -1894122171, -1803064098, 1387788411, -1423715469, 1927414347, -480800993, 1714072405, - -1308153621, 788775605, -2036696123, -744159177, 821200680, 598910399, 45771267, -312704490, - -1976886065, -1483557767, -202313209, 1319232105, 1707996378, 114671109, -786472396, -997523802, - 882725678, -1566550541, 87220618, -1535775754, 188345475, 1084944224, 1577492337, -1118760850, - 1056541217, -1774385443, -575797954, 1296481766, -1850372780, 1896177092, 74437638, 1627329872, - 421854104, -694687299, -1983102144, 1735892697, -1329773848, 126389129, -415737063, 2044456648, - -1589179780, 2095648578, -121037180, 0, 159614592, 843640107, 514617361, 1817080410, - -33816818, 257308805, 1025430958, 908540205, 174381327, 1747035740, -1680780197, 607792694, - 212952842, -1827674281, -1261267218, 463376795, -2142255680, 1638015196, 1516850039, 471210514, - -502613357, -1058723168, 1011081250, 303896347, 235605257, -223492213, 767142070, 348694814, - 1468340721, -1353971851, -289677927, -1543675777, -140564991, 1555887474, 1153776486, 1530167035, - -1955190461, -874723805, -1234633491, -1201409564, -674571215, 1108378979, 322970263, -2078273082, - -2055396278, -755483205, -1374604551, -949116631, 491466654, -588042062, 233591430, 2010178497, - 728503987, -1449543312, 301615252, 1193436393, -1463513860, -1608892432, 1457007741, 586125363, - -2016981431, -641609416, -1929469238, -1741288492, -1496350219, -1524048262, -635007305, 1067761581, - 753179962, 1343066744, 1788595295, 1415726718, -155053171, -1863796520, 777975609, -2097827901, - -1614905251, 1769771984, 1873358293, -810347995, -935618132, 279411992, -395418724, -612648133, - -855017434, 1861490777, -335431782, -2086102449, -429560171, -1434523905, 554225596, -270079979, - -1160143897, 1255028335, -355202657, 701922480, 833598116, 707863359, -969894747, 901801634, - 1949809742, -56178046, -525283184, 857069735, -246769660, 1106762476, 2131644621, 389019281, - 1989006925, 1129165039, -866890326, -455146346, -1629243951, 1276872810, -1044898004, 1182749029, - -1660622242, 22885772, -93096825, -80854773, -1285939865, -1840065829, -382511600, 1829980118, - -1702075945, 930745505, 1502483704, -343327725, -823253079, -1221211807, -504503012, 2050797895, - -1671831598, 1430221810, 410635796, 1941911495, 1407897079, 1599843069, -552308931, 2022103876, - -897453137, -1187068824, 942421028, -1033944925, 376619805, -1140054558, 680216892, -12479219, - 963707304, 148812556, -660806476, 1687208278, 2069988555, -714033614, 1215585388, -800958536 }; - - private static readonly int[] s_iTF = new int[4 * 256] - { - // s_iTF1 - 82, 9, 106, 213, 48, 54, 165, 56, - 191, 64, 163, 158, 129, 243, 215, 251, - 124, 227, 57, 130, 155, 47, 255, 135, - 52, 142, 67, 68, 196, 222, 233, 203, - 84, 123, 148, 50, 166, 194, 35, 61, - 238, 76, 149, 11, 66, 250, 195, 78, - 8, 46, 161, 102, 40, 217, 36, 178, - 118, 91, 162, 73, 109, 139, 209, 37, - 114, 248, 246, 100, 134, 104, 152, 22, - 212, 164, 92, 204, 93, 101, 182, 146, - 108, 112, 72, 80, 253, 237, 185, 218, - 94, 21, 70, 87, 167, 141, 157, 132, - 144, 216, 171, 0, 140, 188, 211, 10, - 247, 228, 88, 5, 184, 179, 69, 6, - 208, 44, 30, 143, 202, 63, 15, 2, - 193, 175, 189, 3, 1, 19, 138, 107, - 58, 145, 17, 65, 79, 103, 220, 234, - 151, 242, 207, 206, 240, 180, 230, 115, - 150, 172, 116, 34, 231, 173, 53, 133, - 226, 249, 55, 232, 28, 117, 223, 110, - 71, 241, 26, 113, 29, 41, 197, 137, - 111, 183, 98, 14, 170, 24, 190, 27, - 252, 86, 62, 75, 198, 210, 121, 32, - 154, 219, 192, 254, 120, 205, 90, 244, - 31, 221, 168, 51, 136, 7, 199, 49, - 177, 18, 16, 89, 39, 128, 236, 95, - 96, 81, 127, 169, 25, 181, 74, 13, - 45, 229, 122, 159, 147, 201, 156, 239, - 160, 224, 59, 77, 174, 42, 245, 176, - 200, 235, 187, 60, 131, 83, 153, 97, - 23, 43, 4, 126, 186, 119, 214, 38, - 225, 105, 20, 99, 85, 33, 12, 125, - - // s_iTF2 - 20992, 2304, 27136, 54528, 12288, 13824, 42240, 14336, - 48896, 16384, 41728, 40448, 33024, 62208, 55040, 64256, - 31744, 58112, 14592, 33280, 39680, 12032, 65280, 34560, - 13312, 36352, 17152, 17408, 50176, 56832, 59648, 51968, - 21504, 31488, 37888, 12800, 42496, 49664, 8960, 15616, - 60928, 19456, 38144, 2816, 16896, 64000, 49920, 19968, - 2048, 11776, 41216, 26112, 10240, 55552, 9216, 45568, - 30208, 23296, 41472, 18688, 27904, 35584, 53504, 9472, - 29184, 63488, 62976, 25600, 34304, 26624, 38912, 5632, - 54272, 41984, 23552, 52224, 23808, 25856, 46592, 37376, - 27648, 28672, 18432, 20480, 64768, 60672, 47360, 55808, - 24064, 5376, 17920, 22272, 42752, 36096, 40192, 33792, - 36864, 55296, 43776, 0, 35840, 48128, 54016, 2560, - 63232, 58368, 22528, 1280, 47104, 45824, 17664, 1536, - 53248, 11264, 7680, 36608, 51712, 16128, 3840, 512, - 49408, 44800, 48384, 768, 256, 4864, 35328, 27392, - 14848, 37120, 4352, 16640, 20224, 26368, 56320, 59904, - 38656, 61952, 52992, 52736, 61440, 46080, 58880, 29440, - 38400, 44032, 29696, 8704, 59136, 44288, 13568, 34048, - 57856, 63744, 14080, 59392, 7168, 29952, 57088, 28160, - 18176, 61696, 6656, 28928, 7424, 10496, 50432, 35072, - 28416, 46848, 25088, 3584, 43520, 6144, 48640, 6912, - 64512, 22016, 15872, 19200, 50688, 53760, 30976, 8192, - 39424, 56064, 49152, 65024, 30720, 52480, 23040, 62464, - 7936, 56576, 43008, 13056, 34816, 1792, 50944, 12544, - 45312, 4608, 4096, 22784, 9984, 32768, 60416, 24320, - 24576, 20736, 32512, 43264, 6400, 46336, 18944, 3328, - 11520, 58624, 31232, 40704, 37632, 51456, 39936, 61184, - 40960, 57344, 15104, 19712, 44544, 10752, 62720, 45056, - 51200, 60160, 47872, 15360, 33536, 21248, 39168, 24832, - 5888, 11008, 1024, 32256, 47616, 30464, 54784, 9728, - 57600, 26880, 5120, 25344, 21760, 8448, 3072, 32000, - - // s_iTF3 - 5373952, 589824, 6946816, 13959168, 3145728, 3538944, 10813440, 3670016, - 12517376, 4194304, 10682368, 10354688, 8454144, 15925248, 14090240, 16449536, - 8126464, 14876672, 3735552, 8519680, 10158080, 3080192, 16711680, 8847360, - 3407872, 9306112, 4390912, 4456448, 12845056, 14548992, 15269888, 13303808, - 5505024, 8060928, 9699328, 3276800, 10878976, 12713984, 2293760, 3997696, - 15597568, 4980736, 9764864, 720896, 4325376, 16384000, 12779520, 5111808, - 524288, 3014656, 10551296, 6684672, 2621440, 14221312, 2359296, 11665408, - 7733248, 5963776, 10616832, 4784128, 7143424, 9109504, 13697024, 2424832, - 7471104, 16252928, 16121856, 6553600, 8781824, 6815744, 9961472, 1441792, - 13893632, 10747904, 6029312, 13369344, 6094848, 6619136, 11927552, 9568256, - 7077888, 7340032, 4718592, 5242880, 16580608, 15532032, 12124160, 14286848, - 6160384, 1376256, 4587520, 5701632, 10944512, 9240576, 10289152, 8650752, - 9437184, 14155776, 11206656, 0, 9175040, 12320768, 13828096, 655360, - 16187392, 14942208, 5767168, 327680, 12058624, 11730944, 4521984, 393216, - 13631488, 2883584, 1966080, 9371648, 13238272, 4128768, 983040, 131072, - 12648448, 11468800, 12386304, 196608, 65536, 1245184, 9043968, 7012352, - 3801088, 9502720, 1114112, 4259840, 5177344, 6750208, 14417920, 15335424, - 9895936, 15859712, 13565952, 13500416, 15728640, 11796480, 15073280, 7536640, - 9830400, 11272192, 7602176, 2228224, 15138816, 11337728, 3473408, 8716288, - 14811136, 16318464, 3604480, 15204352, 1835008, 7667712, 14614528, 7208960, - 4653056, 15794176, 1703936, 7405568, 1900544, 2686976, 12910592, 8978432, - 7274496, 11993088, 6422528, 917504, 11141120, 1572864, 12451840, 1769472, - 16515072, 5636096, 4063232, 4915200, 12976128, 13762560, 7929856, 2097152, - 10092544, 14352384, 12582912, 16646144, 7864320, 13434880, 5898240, 15990784, - 2031616, 14483456, 11010048, 3342336, 8912896, 458752, 13041664, 3211264, - 11599872, 1179648, 1048576, 5832704, 2555904, 8388608, 15466496, 6225920, - 6291456, 5308416, 8323072, 11075584, 1638400, 11862016, 4849664, 851968, - 2949120, 15007744, 7995392, 10420224, 9633792, 13172736, 10223616, 15663104, - 10485760, 14680064, 3866624, 5046272, 11403264, 2752512, 16056320, 11534336, - 13107200, 15400960, 12255232, 3932160, 8585216, 5439488, 10027008, 6356992, - 1507328, 2818048, 262144, 8257536, 12189696, 7798784, 14024704, 2490368, - 14745600, 6881280, 1310720, 6488064, 5570560, 2162688, 786432, 8192000, - - // s_iTF4 - 1375731712, 150994944, 1778384896, -721420288, 805306368, 905969664, -1526726656, 939524096, - -1090519040, 1073741824, -1560281088, -1644167168, -2130706432, -218103808, -687865856, -83886080, - 2080374784, -486539264, 956301312, -2113929216, -1694498816, 788529152, -16777216, -2030043136, - 872415232, -1912602624, 1124073472, 1140850688, -1006632960, -570425344, -385875968, -889192448, - 1409286144, 2063597568, -1811939328, 838860800, -1509949440, -1040187392, 587202560, 1023410176, - -301989888, 1275068416, -1795162112, 184549376, 1107296256, -100663296, -1023410176, 1308622848, - 134217728, 771751936, -1593835520, 1711276032, 671088640, -654311424, 603979776, -1308622848, - 1979711488, 1526726656, -1577058304, 1224736768, 1828716544, -1962934272, -788529152, 620756992, - 1912602624, -134217728, -167772160, 1677721600, -2046820352, 1744830464, -1744830464, 369098752, - -738197504, -1543503872, 1543503872, -872415232, 1560281088, 1694498816, -1241513984, -1845493760, - 1811939328, 1879048192, 1207959552, 1342177280, -50331648, -318767104, -1191182336, -637534208, - 1577058304, 352321536, 1174405120, 1459617792, -1493172224, -1929379840, -1660944384, -2080374784, - -1879048192, -671088640, -1426063360, 0, -1946157056, -1140850688, -754974720, 167772160, - -150994944, -469762048, 1476395008, 83886080, -1207959552, -1291845632, 1157627904, 100663296, - -805306368, 738197504, 503316480, -1895825408, -905969664, 1056964608, 251658240, 33554432, - -1056964608, -1358954496, -1124073472, 50331648, 16777216, 318767104, -1979711488, 1795162112, - 973078528, -1862270976, 285212672, 1090519040, 1325400064, 1728053248, -603979776, -369098752, - -1761607680, -234881024, -822083584, -838860800, -268435456, -1275068416, -436207616, 1929379840, - -1778384896, -1409286144, 1946157056, 570425344, -419430400, -1392508928, 889192448, -2063597568, - -503316480, -117440512, 922746880, -402653184, 469762048, 1962934272, -553648128, 1845493760, - 1191182336, -251658240, 436207616, 1895825408, 486539264, 687865856, -989855744, -1996488704, - 1862270976, -1224736768, 1644167168, 234881024, -1442840576, 402653184, -1107296256, 452984832, - -67108864, 1442840576, 1040187392, 1258291200, -973078528, -771751936, 2030043136, 536870912, - -1711276032, -620756992, -1073741824, -33554432, 2013265920, -855638016, 1509949440, -201326592, - 520093696, -587202560, -1476395008, 855638016, -2013265920, 117440512, -956301312, 822083584, - -1325400064, 301989888, 268435456, 1493172224, 654311424, -2147483648, -335544320, 1593835520, - 1610612736, 1358954496, 2130706432, -1459617792, 419430400, -1258291200, 1241513984, 218103808, - 754974720, -452984832, 2046820352, -1627389952, -1828716544, -922746880, -1677721600, -285212672, - -1610612736, -536870912, 989855744, 1291845632, -1375731712, 704643072, -184549376, -1342177280, - -939524096, -352321536, -1157627904, 1006632960, -2097152000, 1392508928, -1728053248, 1627389952, - 385875968, 721420288, 67108864, 2113929216, -1174405120, 1996488704, -704643072, 637534208, - -520093696, 1761607680, 335544320, 1660944384, 1426063360, 553648128, 201326592, 2097152000 }; - } -} diff --git a/PspCrypto/SHA224Managed_OLD.cs b/PspCrypto/SHA224Managed_OLD.cs deleted file mode 100644 index 81bb30a..0000000 --- a/PspCrypto/SHA224Managed_OLD.cs +++ /dev/null @@ -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 data, Span 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 - }; - } -} diff --git a/PspCrypto/SafeHandles/SafeBignumHandle.cs b/PspCrypto/SafeHandles/SafeBignumHandle.cs deleted file mode 100644 index 36bbe94..0000000 --- a/PspCrypto/SafeHandles/SafeBignumHandle.cs +++ /dev/null @@ -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; } - } - } -} diff --git a/PspCrypto/SafeHandles/SafeEcKeyHandle.cs b/PspCrypto/SafeHandles/SafeEcKeyHandle.cs deleted file mode 100644 index 1057bae..0000000 --- a/PspCrypto/SafeHandles/SafeEcKeyHandle.cs +++ /dev/null @@ -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; - } - } -} diff --git a/PspCrypto/SceMemlmd.cs b/PspCrypto/SceMemlmd.cs index 2f831c2..ea3205c 100644 --- a/PspCrypto/SceMemlmd.cs +++ b/PspCrypto/SceMemlmd.cs @@ -438,7 +438,7 @@ namespace PspCrypto static int Kirk8(Span buf, int size, int use_polling) { int retv; - ref var hdr = ref Utils.AsRef(buf); + ref var hdr = ref MemoryMarshal.AsRef(buf); hdr.mode = KIRKEngine.KIRK_MODE_DECRYPT_CBC; hdr.keyseed = 0x0100; hdr.data_size = size; diff --git a/PspCrypto/SceNpDrm.cs b/PspCrypto/SceNpDrm.cs index f898cb0..c1ee853 100644 --- a/PspCrypto/SceNpDrm.cs +++ b/PspCrypto/SceNpDrm.cs @@ -1,1322 +1,1321 @@ -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 -{ - public static class SceNpDrm - { - unsafe struct SceEbootPbp - { - public ulong Magic; - public int KeyType; - public int Type; - private fixed byte _contentId[0x30]; - - public Span ContentId - { - get - { - fixed (byte* ptr = _contentId) - { - return new Span(ptr, 0x30); - } - } - } - - public ulong Aid; - public ulong SecureTick; - public long PbpSize; - public int SwVer; - public int DiscCount; - private fixed long _discOffsets[6]; - - public Span DiscOffsets - { - get - { - fixed (long* ptr = _discOffsets) - { - return new Span(ptr, 6); - } - } - } - private fixed byte _padding[0xC8]; - private fixed byte _pbpHdrSig[0x38]; - - public Span PbpHdrSig - { - get - { - fixed (byte* ptr = _pbpHdrSig) - { - return new Span(ptr, 0x38); - } - } - } - private fixed byte _npUmdImgSig[0x38]; - - public Span NpUmdImgSig - { - get - { - fixed (byte* ptr = _npUmdImgSig) - { - return new Span(ptr, 0x38); - } - } - } - private fixed byte _sig[0x38]; - - public Span Sig - { - get - { - fixed (byte* ptr = _sig) - { - return new Span(ptr, 0x38); - } - } - } - } - unsafe struct SceEbootPbp100 - { - public ulong Magic; - public int KeyType; - public int Type; - private fixed byte _contentId[0x30]; - - public Span ContentId - { - get - { - fixed (byte* ptr = _contentId) - { - return new Span(ptr, 0x30); - } - } - } - private fixed byte _padding[0x18]; - private fixed byte _pbpHdrSig[0x38]; - - public Span PbpHdrSig - { - get - { - fixed (byte* ptr = _pbpHdrSig) - { - return new Span(ptr, 0x38); - } - } - } - private fixed byte _npUmdImgSig[0x38]; - - public Span NpUmdImgSig - { - get - { - fixed (byte* ptr = _npUmdImgSig) - { - return new Span(ptr, 0x38); - } - } - } - private fixed byte _sig[0x38]; - - public Span Sig - { - get - { - fixed (byte* ptr = _sig) - { - return new Span(ptr, 0x38); - } - } - } - } - - unsafe struct sceDiscInfo - { - private fixed byte _id[0x30]; - - public Span Id - { - get - { - fixed (byte* ptr = _id) - { - return new Span(ptr, 0x30); - } - } - } - - public int Version; - public int DiscCount; - public long FileSize; - private fixed long _diskOffsets[6]; - - public Span Offsets - { - get - { - fixed (long* ptr = _diskOffsets) - { - return new Span(ptr, 6); - } - } - } - - private fixed byte _pad[0x20]; - private fixed byte _discsSig[0x38]; - - public Span DiscsSig - { - get - { - fixed (byte* ptr = _discsSig) - { - return new Span(ptr, 0x38); - } - } - } - private fixed byte _sig[0x38]; - - public Span Sig - { - get - { - fixed (byte* ptr = _sig) - { - return new Span(ptr, 0x38); - } - } - } - - } - - public static ulong Aid { get; set; } - - public static byte[] SceDiskInfo => Resource.__sce_discinfo; - - private const int BLK_SIZE = 0x7C0; - - private static readonly Memory _memory = new byte[0x1000]; - - private static byte[] _psId; - - private static long _fuseId; - - public static void SetPSID(byte[] psid) - { - _psId = psid; - } - - public static void SetFuseId(long fuseId) - { - _fuseId = fuseId; - } - - public static void SetFuseId(Span fuseId) - { - SetFuseId(MemoryMarshal.Read(fuseId)); - } - - public unsafe struct SceNpDrmKey - { - private fixed byte _KeyData[16]; - public Span KeyData - { - get - { - fixed (byte* ptr = _KeyData) - { - return new Span(ptr, 16); - } - } - } - } - - [StructLayout(LayoutKind.Sequential)] - public unsafe struct Rif - { - private short _version; - private short _versionFlag; - private int _drmType; - private fixed byte _accountId[8]; - private fixed byte _contentId[0x30]; - private fixed byte _encKey1[0x10]; - private fixed byte _encKey2[0x10]; - private long _startTime; - private long _endTime; - private fixed byte _ecdsaSig[0x28]; - public short Version => _version; - public short VersionFlag => _versionFlag; - public int DrmType => _drmType; - public Span AccountId - { - get - { - fixed (byte* ptr = _accountId) - { - return new Span(ptr, 8); - } - } - } - public Span ContentId - { - get - { - fixed (byte* ptr = _contentId) - { - return new Span(ptr, 0x30); - } - } - } - public Span EncKey1 - { - get - { - fixed (byte* ptr = _encKey1) - { - return new Span(ptr, 0x10); - } - } - } - public Span EncKey2 - { - get - { - fixed (byte* ptr = _encKey2) - { - return new Span(ptr, 0x10); - } - } - } - public long StartTime => _startTime; - public long EndTime => _endTime; - - public Span EcdsaSig - { - get - { - fixed (byte* ptr = _ecdsaSig) - { - return new Span(ptr, 0x28); - } - } - } - } - - [StructLayout(LayoutKind.Sequential)] - public unsafe struct Act - { - private short _actType; - private short _versionFlag; - private int _version; - private fixed byte _accountId[8]; - private fixed byte _primKeyTable[0x800]; - private fixed byte _unk1[0x40]; - private fixed byte _openPsId[0x10]; - private fixed byte _unk2[0x10]; - private fixed byte _unk4[0x10]; - private fixed byte _secondTable[0x650]; - private fixed byte _rsaSig[0x100]; - private fixed byte _unkSig[0x40]; - private fixed byte _ecdsaSig[0x28]; - public short ActType => _actType; - public short VersionFlag => _versionFlag; - public int Version => _version; - public Span AccountId - { - get - { - fixed (byte* ptr = _accountId) - { - return new Span(ptr, 8); - } - } - } - public Span PrimKeyTable - { - get - { - fixed (byte* ptr = _primKeyTable) - { - return new Span(ptr, 0x800); - } - } - } - public Span Unk1 - { - get - { - fixed (byte* ptr = _unk1) - { - return new Span(ptr, 0x40); - } - } - } - public Span OpenPsId - { - get - { - fixed (byte* ptr = _openPsId) - { - return new Span(ptr, 0x10); - } - } - } - public Span Unk2 - { - get - { - fixed (byte* ptr = _unk2) - { - return new Span(ptr, 0x10); - } - } - } - public Span Unk4 - { - get - { - fixed (byte* ptr = _unk4) - { - return new Span(ptr, 0x10); - } - } - } - public Span SecondTable - { - get - { - fixed (byte* ptr = _secondTable) - { - return new Span(ptr, 0x650); - } - } - } - public Span RsaSig - { - get - { - fixed (byte* ptr = _rsaSig) - { - return new Span(ptr, 0x100); - } - } - } - public Span UnkSig - { - get - { - fixed (byte* ptr = _unkSig) - { - return new Span(ptr, 0x40); - } - } - } - public Span EcdsaSig - { - get - { - fixed (byte* ptr = _ecdsaSig) - { - return new Span(ptr, 0x28); - } - } - } - - } - - public static int sceNpDrmGetIDps(Span idps) - { - if (_psId != null && idps != null) - { - _psId.CopyTo(idps); - return 0; - } - return -0x7faaf6ff; - } - - private static int GetActKey(Span key, ReadOnlySpan keyTable, int count) - { - Span idps = stackalloc byte[16]; - Span decKey = stackalloc byte[16]; - int ret = sceNpDrmGetIDps(idps); - if (ret > -1) - { - ret = AesHelper.AesEncrypt(KeyVault.drmActdatKey, decKey, idps); - if (ret == 16) - { - for (int i = 0; i < count; i++) - { - ret = AesHelper.AesDecrypt(keyTable[(i * 0x10)..], key[(i * 0x10)..], decKey); - if (ret != 16) - { - ret = unchecked((int)0x80550902); - break; - } - } - ret = 0; - } - } - idps.Clear(); - decKey.Clear(); - return ret; - } - - private static int GetFreeVersionKey(Span versionKey, ReadOnlySpan rifBuf) - { - return -1; - } - - private static int GetLicenseVersionKey(Span versionKey, ReadOnlySpan actBuf, ReadOnlySpan rifBuf) - { - Span buf1 = stackalloc byte[16]; - Span buf2 = stackalloc byte[16]; - int ret = sceNpDrmVerifyAct(actBuf); - if (ret > -1) - { - ret = sceNpDrmVerifyRif(rifBuf); - if (ret > -1) - { - var act = MemoryMarshal.AsRef(actBuf); - var rif = MemoryMarshal.AsRef(rifBuf); - if (!act.AccountId.SequenceEqual(rif.AccountId)) - { - return -0x7faaf6fb; - } - if (((act.ActType & 0xff) << 8 | act.ActType >> 8) < ((rif.Version & 0xff) << 8 | rif.Version >> 9)) - { - return -0x7faaf6ef; - } - AesHelper.AesDecrypt(rif.EncKey1, buf1, KeyVault.drmRifKey); - int keyIdx = MemoryMarshal.Read(buf1[12..]); - keyIdx >>= 0x18; - if (keyIdx >= 0x80) - { - return -0x7faaf6fe; - } - ret = GetActKey(buf2, act.PrimKeyTable[(keyIdx * 0x10)..], 1); - if (ret > -1) - { - ret = AesHelper.AesDecrypt(rif.EncKey2, versionKey, buf2); - if (ret != 16) - { - ret = -0x7faaf6fe; - } - } - } - } - buf1.Clear(); - buf2.Clear(); - return ret; - } - - private static int CheckRifExpress(ReadOnlySpan rifBuf) - { - // TODO - return 0; - } - - private static int GenVersionKey(Span versionKey, int type) - { - type &= 0xffffff; - int ret = 0; - if (type != 0) - { - ret = unchecked((int)0x80550901); - if (type < 4) - { - ret = AesHelper.AesEncrypt(versionKey, versionKey, KeyVault.drmVersionKeyKey.AsSpan().Slice(type * 0x10, 0x10)); - ret = ret == 16 ? 0 : unchecked((int)0x80550902); - } - } - return ret; - } - - public static int sceNpDrmGetVersionKey(Span versionKey, ReadOnlySpan actBuf, ReadOnlySpan rifBuf, int type) - { - int ret = -0x7faaf6ff; - if (versionKey != null && rifBuf != null) - { - var rif = MemoryMarshal.AsRef(rifBuf); - if (rif.DrmType == 0x300000) - { - ret = GetFreeVersionKey(versionKey, rifBuf); - } - else - { - if (actBuf == null) - { - return ret; - } - ret = GetLicenseVersionKey(versionKey, actBuf, rifBuf); - } - if (ret > -1) - { - ret = CheckRifExpress(rifBuf); - if (ret > -1) - { - ret = GenVersionKey(versionKey, type); - } - } - } - return ret; - } - - public static int sceNpDrmGetFixedKey(Span fixedKey, ReadOnlySpan contentId, int type) - { - Span buf = stackalloc byte[0x30]; - Span mkey = stackalloc byte[48]; - int ret = -0x7faaf6ff; - if ((type & 0x1000000) != 0) - { - contentId[..0x30].CopyTo(buf); - ret = AMCTRL.sceDrmBBMacInit(mkey, 1); - if (ret == 0) - { - ret = AMCTRL.sceDrmBBMacUpdate(mkey, buf, 0x30); - if (ret == 0) - { - ret = AMCTRL.sceDrmBBMacFinal(mkey, fixedKey, KeyVault.DrmFixedKey); - if (ret == 0) - { - ret = GenVersionKey(fixedKey, (int)(type & 0xfeffffff)); - } - else - { - ret = -0x7faaf6fe; - } - } - } - } - return ret; - } - - public static int sceNpDrmGetContentKey(Span contentKey, ReadOnlySpan actBuf, ReadOnlySpan rifBuf) => sceNpDrmGetVersionKey(contentKey, actBuf, rifBuf, 0); - - public static int sceNpDrmVerifyAct(ReadOnlySpan actBuf) - { - int ret = -0x7faaf6ff; - if (actBuf != null) - { - ret = -0x7faaf6fa; - var act = MemoryMarshal.AsRef(actBuf); - if (((act.VersionFlag & 0xFF) << 8 | act.VersionFlag >> 8) < 2) - { - if (((act.ActType & 0xFF) << 8 | act.ActType >> 8) < 2) - { - ret = VerifySig(act.EcdsaSig, KeyVault.drmActRifSig, actBuf, 0x1010); - } - } - } - return ret; - } - - private static int VerifySig(ReadOnlySpan sig, ReadOnlySpan pubKey, ReadOnlySpan data, int dataSize) - { - int ret; - Span digest = stackalloc byte[32]; - if (dataSize < 0x801) - { - ret = SceDdrdb.sceDdrdbHash(data, dataSize, digest); - } - else - { - ret = (SHA1.HashData(data[..dataSize], digest) > 0 ? 0 : -1); - } - if (ret > -1) - { - ret = SceDdrdb.sceDdrdbSigvry(pubKey, digest, sig); - } - return ret; - } - - private static int FillFuseId(Span fuseId) - { - if (_fuseId != 0) - { - uint heigh = (uint)((_fuseId >> 32) & 0xffffffff); - uint low = (uint)(_fuseId & 0xffffffff); - fuseId[0] = BinaryPrimitives.ReverseEndianness(heigh); - fuseId[1] = BinaryPrimitives.ReverseEndianness(low); - } - return -1; - } - - private static int VerifyRif(ReadOnlySpan rifBuf) - { - int ret = -0x7faaf6ff; - if (rifBuf != null) - { - ret = -0x7faaf6fa; - var rif = MemoryMarshal.AsRef(rifBuf); - if (((rif.VersionFlag & 0xff) << 8 | rif.VersionFlag >> 8) < 3) - { - if (((rif.Version & 0xff) << 8 | rif.Version >> 8) < 2) - { - int ret2; - if ((rif.DrmType & 0x10000) == 0) - { - ret = VerifySig(rif.EcdsaSig, KeyVault.drmActRifSig, rifBuf, 0x70); - ret2 = -0x7faaf6fc; - } - else - { - Span buffer = stackalloc byte[0x90]; - rifBuf[..0x70].CopyTo(buffer); - if (_psId == null) - { - return ret; - } - ret = sceNpDrmGetIDps(buffer[0x70..]); - if (ret < 0) - { - return ret; - } - Span fuseId = MemoryMarshal.Cast(buffer[0x80..]); - ret = FillFuseId(fuseId); - if (ret < 0) - { - return ret; - } - ret = VerifySig(rif.EcdsaSig, KeyVault.drmActRifSig, buffer, 0x90); - ret2 = -0x7faaf6e8; - } - if (ret != 0) - { - ret = ret2; - } - } - } - } - return ret; - } - - public static int sceNpDrmVerifyRif(ReadOnlySpan rifBuf) - { - int ret = VerifyRif(rifBuf); - if (ret > -1) - { - var rif = MemoryMarshal.AsRef(rifBuf); - if (rif.DrmType == 0x3000000) - { - ret = -1; // TODO - } - } - return ret; - } - - public static int KsceNpDrmEbootSigGenMultiDisc(string fileName, ReadOnlySpan sceDiscInfo, - Span ebootSig, int swVer) - { - return SceNpDrmEbootSigGenMultiDisc(fileName, sceDiscInfo, ebootSig, swVer, _memory.Span, BLK_SIZE); - } - public static int KsceNpDrmEbootSigGenPs1(Stream file, Span ebootSig, int swVer) - { - return SceNpDrmEbootSigGen(file, 3, ebootSig, swVer, _memory.Span, BLK_SIZE); - } - - public static int KsceNpDrmEbootSigGenPsp(Stream file, Span ebootSig, int swVer) - { - return SceNpDrmEbootSigGen(file, 2, ebootSig, swVer, _memory.Span, BLK_SIZE); - } - - public static int KsceNpDrmPspEbootSigGen(Stream file, Span ebootSig) - { - return SceNpDrmPspEbootSigGen(file, ebootSig, _memory.Span, BLK_SIZE); - } - - public static int KsceNpDrmEbootSigGenPs1(string fileName, Span ebootSig, int swVer) - { - return SceNpDrmEbootSigGen(fileName, 3, ebootSig, swVer, _memory.Span, BLK_SIZE); - } - - public static int KsceNpDrmEbootSigGenPsp(string fileName, Span ebootSig, int swVer) - { - return SceNpDrmEbootSigGen(fileName, 2, ebootSig, swVer, _memory.Span, BLK_SIZE); - } - - public static int KsceNpDrmPspEbootSigGen(string fileName, Span ebootSig) - { - return SceNpDrmPspEbootSigGen(fileName, ebootSig, _memory.Span, BLK_SIZE); - } - - private static int SceNpDrmEbootSigGenMultiDisc(string fileName, ReadOnlySpan sceDiskInfo, - Span ebootSig, int swVer, Span buffer, int blockSize) - { - Span pbpHdrDigest = stackalloc byte[32]; - Span discsDigest = stackalloc byte[32]; - Span ebootSigtmp = stackalloc byte[512]; - ref var sceEbootPbp = ref Utils.AsRef(ebootSigtmp); - if ((blockSize & 0x3F) != 0) - { - blockSize &= unchecked((int)0xFFFFFFC0); - } - - if (sceDiskInfo == null || string.IsNullOrWhiteSpace(fileName) || buffer == null || ebootSig == null || - blockSize < 0x400) - { - return unchecked((int)0x80870001); - } - - Span secureTick = stackalloc byte[8] { 0xD4, 0x7A, 0x2C, 0x13, 0x64, 0x59, 0xE2, 0x00 }; - //RandomNumberGenerator.Fill(secureTick); - - ebootSig.Fill(0); - sceEbootPbp.SwVer = swVer; - sceEbootPbp.Aid = Aid; - sceEbootPbp.SecureTick = Utils.AsRef(secureTick); - - var sha224 = SHA224.Create(); - var hash = sha224.ComputeHash(sceDiskInfo[..200].ToArray()); - var ret = SceSblGcAuthMgrDrmBBForDriver_4B506BE7(hash, sceDiskInfo[200..], 1000); - if (ret != 0) - { - return ret; - } - - var discInfo = Utils.AsRef(sceDiskInfo); - ret = unchecked((int)0x80870005); - if (discInfo.DiscCount > 6) - { - return ret; - } - var fi = new FileInfo(fileName); - if (!fi.Exists) - { - return -1; - } - - if (fi.Length != discInfo.FileSize) - { - return ret; - } - - ret = unchecked((int)0x80870001); - if (discInfo.DiscCount < 7) - { - if (fi.Length < discInfo.Offsets[0]) - { - return ret; - } - if (discInfo.DiscCount > 1 && fi.Length < discInfo.Offsets[1]) - { - return ret; - } - if (discInfo.DiscCount > 2 && fi.Length < discInfo.Offsets[2]) - { - return ret; - } - if (discInfo.DiscCount > 3 && fi.Length < discInfo.Offsets[3]) - { - return ret; - } - if (discInfo.DiscCount > 4 && fi.Length < discInfo.Offsets[4]) - { - return ret; - } - if (discInfo.DiscCount > 5 && fi.Length < discInfo.Offsets[5]) - { - return ret; - } - - using var stream = fi.OpenRead(); - ret = SceMultiDiscDigest(stream, fi.Length, discInfo.DiscCount, discInfo.Offsets, pbpHdrDigest, discsDigest, buffer, blockSize); - if (discInfo.DiscCount >= 0) - { - stream.Close(); - ret = SceSblGcAuthMgrDrmBBForDriver_4B506BE7(discsDigest, discInfo.DiscsSig, 1000); - if (ret != 0) - { - return ret; - } - - sceEbootPbp.PbpSize = fi.Length; - sceEbootPbp.Magic = 0x47495349544C554D; - sceEbootPbp.KeyType = 1; - sceEbootPbp.Type = 4; - discInfo.Id.CopyTo(sceEbootPbp.ContentId); - sceEbootPbp.DiscCount = discInfo.DiscCount; - discInfo.Offsets.CopyTo(sceEbootPbp.DiscOffsets); - ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(pbpHdrDigest, sceEbootPbp.PbpHdrSig, 1); - if (ret != 0) - { - return ret; - } - discInfo.DiscsSig.CopyTo(sceEbootPbp.NpUmdImgSig); - var ebootsigDigst = sha224.ComputeHash(ebootSigtmp.Slice(0, 0x1C8).ToArray()); - ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(ebootsigDigst, sceEbootPbp.Sig, 1); - if (ret != 0) - { - return ret; - } - ebootSigtmp.CopyTo(ebootSig); - ret = 0; - } - } - return ret; - } - - private static int SceMultiDiscDigest(Stream stream, long fileSize, int diskCount, - ReadOnlySpan diskOffsets, Span pbpHdrDigest, Span dataDigest, Span buffer, - int blockSize) - { - var sha224 = SHA224.Create(); - var ret = unchecked((int)0x80870005); - stream.Seek(0, SeekOrigin.Begin); - buffer = buffer.Slice(0, blockSize); - var readSize = stream.Read(buffer); - if (readSize < 0x28) - { - return ret; - } - var pbpHeader = Utils.AsRef(buffer); - if (pbpHeader.Sig != 0x50425000) - { - return ret; - } - - var tmp = readSize; - if (pbpHeader.DataPsarOff < readSize) - { - tmp = pbpHeader.DataPsarOff; - } - - var paramReadSize = pbpHeader.Icon0Off; - if (paramReadSize > 0x400) - { - paramReadSize = 0x400; - } - - if (tmp < paramReadSize) - { - return ret; - } - - sha224.TransformFinalBlock(buffer.ToArray(), 0, paramReadSize); - sha224.Hash.CopyTo(pbpHdrDigest); - - sha224.Initialize(); - sha224.TransformBlock(buffer.ToArray(), 0, paramReadSize, null, 0); - - long end = pbpHeader.DataPsarOff + 0xC0000; - if (diskOffsets[0] >= pbpHeader.DataPsarOff && diskOffsets[0] < end) - { - end = diskOffsets[0]; - } - - long start = pbpHeader.DataPsarOff; - stream.Seek(start, SeekOrigin.Begin); - for (; start < end; start += readSize) - { - var toRead = (int)(end - start); - if (toRead > blockSize) - { - toRead = blockSize; - } - - readSize = stream.Read(buffer.Slice(0, toRead)); - if (readSize == 0) - { - return -1; - } - sha224.TransformBlock(buffer.ToArray(), 0, readSize, null, 0); - } - - if (diskCount != 0) - { - var start1 = diskOffsets[0]; - end = diskOffsets[0] + 0xC0000; - if (end >= 0) - { - var discNo = 0; - var idx = 5; - while (true) - { - if (fileSize < end) - { - end = fileSize; - } - - if (++discNo < diskCount) - { - start = diskOffsets[idx - 4]; - if (start >= start1 && start < end) - { - end = start; - } - } - - if (start1 < end) - { - stream.Seek(start1, SeekOrigin.Begin); - while (true) - { - var toRead = (int)(end - start1); - if (toRead > blockSize) - { - toRead = blockSize; - } - - readSize = stream.Read(buffer.Slice(0, toRead)); - if (readSize == 0) - { - return -1; - } - sha224.TransformBlock(buffer.ToArray(), 0, readSize, null, 0); - start1 += toRead; - if (start1 >= end) - { - break; - } - } - } - - if (discNo == diskCount) - { - break; - } - start1 = diskOffsets[idx - 4]; - idx++; - end = start1 + 0xC0000; - - } - } - } - sha224.TransformFinalBlock(buffer.ToArray(), 0, 0); - sha224.Hash.CopyTo(dataDigest); - - stream.Seek(pbpHeader.DataPsarOff, SeekOrigin.Begin); - readSize = stream.Read(buffer.Slice(0, 0x100)); - if (readSize == 0x100) - { - ret = 0; - } - else - { - ret = unchecked((int)0x80870005); - } - - return ret; - } - - private static int SceNpDrmEbootSigGen(string fileName, int type, Span ebootSig, int swVer, Span buffer, int blockSize) - { - if(string.IsNullOrWhiteSpace(fileName)) return -0x7f78ffff; - var fi = new FileInfo(fileName); - if (!fi.Exists) - { - return -1; - } - using(FileStream fstream = fi.OpenRead()){ - return SceNpDrmEbootSigGen(fstream, type, ebootSig, swVer, buffer, blockSize); - } - - } - private static int SceNpDrmEbootSigGen(Stream ebootStream, int type, Span ebootSig, int swVer, Span buffer, int blockSize) - { - Span pbpHdrDigest = stackalloc byte[32]; - Span npUmdImgDigest = stackalloc byte[32]; - Span ebootSigtmp = stackalloc byte[512]; - ref var sceEbootPbp = ref Utils.AsRef(ebootSigtmp); - if ((blockSize & 0x3F) != 0) - { - blockSize &= unchecked((int)0xFFFFFFC0); - } - - if (ebootStream == null || buffer == null || ebootSig == null || blockSize < 0x400 || type > 3) - { - return -0x7f78ffff; - } - - Span secureTick = BitConverter.GetBytes(ksceRtcGetCurrentSecureTick()); - - ebootSig.Fill(0); - sceEbootPbp.SwVer = swVer; - sceEbootPbp.Aid = Aid; - sceEbootPbp.SecureTick = Utils.AsRef(secureTick); - - long flen = ebootStream.Length; - int ret = SceEbootPbpDigest(ebootStream, flen, pbpHdrDigest, npUmdImgDigest, buffer, blockSize); - if (ret < 0) - { - return ret; - } - - sceEbootPbp.KeyType = 1; - sceEbootPbp.PbpSize = flen; - sceEbootPbp.Type = type; - var psarSig = Encoding.ASCII.GetString(buffer.Slice(0, 8)); - if (type == 3) - { - if (psarSig != "PSISOIMG") - { - return -0x7f78fffb; - } - sceEbootPbp.Magic = 0x474953315350504E; - } - else - { - if (psarSig != "NPUMDIMG") - { - return -0x7f78fffb; - } - - sceEbootPbp.Magic = 0x474953444D55504E; - buffer.Slice(0x10, 0x30).CopyTo(sceEbootPbp.ContentId); - } - - ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(pbpHdrDigest, sceEbootPbp.PbpHdrSig, 1); - if (ret < 0) - { - return ret; - } - - ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(npUmdImgDigest, sceEbootPbp.NpUmdImgSig, 1); - if (ret < 0) - { - return ret; - } - - var sha224 = SHA224.Create(); - var ebootsigDigst = sha224.ComputeHash(ebootSigtmp.Slice(0, 0x1C8).ToArray()); - ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(ebootsigDigst, sceEbootPbp.Sig, 1); - if (ret < 0) - { - return ret; - } - ebootSigtmp.CopyTo(ebootSig); - ret = 0; - return ret; - } - - private static int SceEbootPbpDigest(Stream stream, long fileSize, Span pbpHdrDigest, - Span npUmdImgDigest, Span buffer, int blockSize) - { - var sha224 = SHA224.Create(); - var ret = unchecked((int)0x80870005); - stream.Seek(0, SeekOrigin.Begin); - buffer = buffer.Slice(0, blockSize); - var readSize = stream.Read(buffer); - if (readSize < 0x28) - { - return ret; - } - - var pbpHeader = Utils.AsRef(buffer); - if (fileSize < pbpHeader.DataPsarOff + 0xFF || pbpHeader.Sig != 0x50425000) - { - return ret; - } - - var tmp = readSize; - if (pbpHeader.DataPsarOff < readSize) - { - tmp = pbpHeader.DataPsarOff; - } - - var paramReadSize = pbpHeader.Icon0Off; - if (paramReadSize > 0x400) - { - paramReadSize = 0x400; - } - - if (tmp < paramReadSize) - { - return ret; - } - - sha224.TransformFinalBlock(buffer.ToArray(), 0, paramReadSize); - sha224.Hash.CopyTo(pbpHdrDigest); - - sha224.Initialize(); - - var alignedFileSize = (pbpHeader.DataPsarOff + 0x1C0000 + 64 - 1) & ~(64 - 1); - if (alignedFileSize < fileSize) - { - fileSize = alignedFileSize; - } - - var fixsize2 = fileSize; - if (pbpHeader.DataPsarOff + 0x1C0000 < fileSize) - { - fixsize2 = pbpHeader.DataPsarOff + 0x1C0000; - } - - if (pbpHeader.DataPsarOff < fixsize2) - { - var offset = pbpHeader.DataPsarOff; - stream.Seek(offset, SeekOrigin.Begin); - while (true) - { - readSize = stream.Read(buffer); - var bsize = readSize; - if (readSize <= 0) - { - ret = unchecked((int)0x80870002); - return ret; - } - - if (fixsize2 < offset + readSize) - { - bsize = (int)(fixsize2 - offset); - } - sha224.TransformBlock(buffer.ToArray(), 0, bsize, null, 0); - - offset += readSize; - if (offset >= fixsize2) - { - break; - } - } - sha224.TransformFinalBlock(buffer.ToArray(), 0, 0); - sha224.Hash.CopyTo(npUmdImgDigest); - stream.Seek(pbpHeader.DataPsarOff, SeekOrigin.Begin); - readSize = stream.Read(buffer.Slice(0, 0x100)); - if (readSize == 0x100) - { - ret = 0; - } - else - { - ret = unchecked((int)0x80870005); - } - } - - - return ret; - } - - private static int SceNpDrmPspEbootSigGen(string fileName, Span ebootSig, Span buffer, int blockSize) - { - if(string.IsNullOrWhiteSpace(fileName)) - return -0x7f78ffff; - - var fi = new FileInfo(fileName); - if (!fi.Exists) - { - return -1; - } - using(FileStream fs = fi.OpenRead()) - { - return SceNpDrmPspEbootSigGen(fs, ebootSig, buffer, blockSize); - } - } - - private static int SceNpDrmPspEbootSigGen(Stream ebootStream, Span ebootSig, Span buffer,int blockSize) - { - Span pbpHdrDigest = stackalloc byte[32]; - Span npUmdImgDigest = stackalloc byte[32]; - Span ebootSigtmp = stackalloc byte[0x100]; - ref var sceEbootPbp = ref Utils.AsRef(ebootSigtmp); - if ((blockSize & 0x3F) != 0) - { - blockSize &= unchecked((int)0xFFFFFFC0); - } - - if (ebootStream == null || buffer == null || ebootSig == null || blockSize < 0x400) - { - return -0x7f78ffff; - } - - long fileSize = ebootStream.Length; - int ret = SceEbootPbpDigest(ebootStream, fileSize, pbpHdrDigest, npUmdImgDigest, buffer, blockSize); - if (ret < 0) - { - return ret; - } - - if (Encoding.ASCII.GetString(buffer.Slice(0, 8)) != "NPUMDIMG") - { - return -0x7f78fffb; - } - buffer.Slice(0, 0x40).CopyTo(ebootSigtmp); - sceEbootPbp.Type = 0; - sceEbootPbp.Magic = 0x474953444D55504E; - - ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(pbpHdrDigest, sceEbootPbp.PbpHdrSig, 1); - if (ret < 0) - { - return ret; - } - - ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(npUmdImgDigest, sceEbootPbp.NpUmdImgSig, 1); - if (ret < 0) - { - return ret; - } - - var sha224 = SHA224.Create(); - var ebootsigDigst = sha224.ComputeHash(ebootSigtmp.Slice(0, 0xC8).ToArray()); - ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(ebootsigDigst, sceEbootPbp.Sig, 1); - if (ret < 0) - { - return ret; - } - ebootSigtmp.CopyTo(ebootSig); - ret = 0; - - return ret; - } - - private static int SceSblGcAuthMgrDrmBBForDriver_050DC6DF(ReadOnlySpan digest, Span sig, int type) - { - var curve = ECDsaHelper.SetCurve(KeyVault.Eboot_p, KeyVault.Eboot_a, KeyVault.Eboot_b, KeyVault.Eboot_N, KeyVault.Eboot_Gx, - KeyVault.Eboot_Gy); - using var ecdsa = ECDsaHelper.Create(curve, - KeyVault.Eboot_priv[type], - KeyVault.Eboot_pubx[type], - KeyVault.Eboot_puby[type], true); - var signature = ecdsa.SignHash(digest.ToArray()); - signature.CopyTo(sig); - return 0; - } - - private static ulong ksceRtcGetCurrentSecureTick() - { - DateTime epoch = new DateTime(1, 1, 1, 0, 0, 0); - DateTime now = DateTime.UtcNow; - TimeSpan ts = now.Subtract(epoch); - return Convert.ToUInt64(Math.Floor(ts.TotalMilliseconds)) * 1000; - } - - private static int SceSblGcAuthMgrDrmBBForDriver_4B506BE7(ReadOnlySpan digest, ReadOnlySpan sig, int keyType) - { - byte[] pubx; - byte[] puby; - switch (keyType) - { - case 1: - pubx = KeyVault.VitaKirk18PubKey1x; - puby = KeyVault.VitaKirk18PubKey1y; - break; - case 0: - pubx = KeyVault.VitaKirk18PubKey0x; - puby = KeyVault.VitaKirk18PubKey0y; - break; - case 1000: - pubx = KeyVault.VitaKirk18PubKey1000x; - puby = KeyVault.VitaKirk18PubKey1000y; - break; - default: - return unchecked((int)0x808a040a); - } - var curve = ECDsaHelper.SetCurve(KeyVault.Eboot_p, KeyVault.Eboot_a, KeyVault.Eboot_b, KeyVault.Eboot_N, KeyVault.Eboot_Gx, - KeyVault.Eboot_Gy); - using var ecdsa = ECDsaHelper.Create(curve, pubx, puby); - var verify = ecdsa.VerifyHash(digest.ToArray(), sig.ToArray()); - - return verify ? 0 : -1; - } - } -} +using PspCrypto.Security.Cryptography; +using System; +using System.Buffers.Binary; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Security.Cryptography; +using System.Text; + +namespace PspCrypto +{ + public static class SceNpDrm + { + unsafe struct SceEbootPbp + { + public ulong Magic; + public int KeyType; + public int Type; + private fixed byte _contentId[0x30]; + + public Span ContentId + { + get + { + fixed (byte* ptr = _contentId) + { + return new Span(ptr, 0x30); + } + } + } + + public ulong Aid; + public ulong SecureTick; + public long PbpSize; + public int SwVer; + public int DiscCount; + private fixed long _discOffsets[6]; + + public Span DiscOffsets + { + get + { + fixed (long* ptr = _discOffsets) + { + return new Span(ptr, 6); + } + } + } + private fixed byte _padding[0xC8]; + private fixed byte _pbpHdrSig[0x38]; + + public Span PbpHdrSig + { + get + { + fixed (byte* ptr = _pbpHdrSig) + { + return new Span(ptr, 0x38); + } + } + } + private fixed byte _npUmdImgSig[0x38]; + + public Span NpUmdImgSig + { + get + { + fixed (byte* ptr = _npUmdImgSig) + { + return new Span(ptr, 0x38); + } + } + } + private fixed byte _sig[0x38]; + + public Span Sig + { + get + { + fixed (byte* ptr = _sig) + { + return new Span(ptr, 0x38); + } + } + } + } + unsafe struct SceEbootPbp100 + { + public ulong Magic; + public int KeyType; + public int Type; + private fixed byte _contentId[0x30]; + + public Span ContentId + { + get + { + fixed (byte* ptr = _contentId) + { + return new Span(ptr, 0x30); + } + } + } + private fixed byte _padding[0x18]; + private fixed byte _pbpHdrSig[0x38]; + + public Span PbpHdrSig + { + get + { + fixed (byte* ptr = _pbpHdrSig) + { + return new Span(ptr, 0x38); + } + } + } + private fixed byte _npUmdImgSig[0x38]; + + public Span NpUmdImgSig + { + get + { + fixed (byte* ptr = _npUmdImgSig) + { + return new Span(ptr, 0x38); + } + } + } + private fixed byte _sig[0x38]; + + public Span Sig + { + get + { + fixed (byte* ptr = _sig) + { + return new Span(ptr, 0x38); + } + } + } + } + + unsafe struct SceDiscInfo + { + private fixed byte _id[0x30]; + + public Span Id + { + get + { + fixed (byte* ptr = _id) + { + return new Span(ptr, 0x30); + } + } + } + + public int Version; + public int DiscCount; + public long FileSize; + private fixed long _diskOffsets[6]; + + public Span Offsets + { + get + { + fixed (long* ptr = _diskOffsets) + { + return new Span(ptr, 6); + } + } + } + + private fixed byte _pad[0x20]; + private fixed byte _discsSig[0x38]; + + public Span DiscsSig + { + get + { + fixed (byte* ptr = _discsSig) + { + return new Span(ptr, 0x38); + } + } + } + private fixed byte _sig[0x38]; + + public Span Sig + { + get + { + fixed (byte* ptr = _sig) + { + return new Span(ptr, 0x38); + } + } + } + + } + + public static ulong Aid { get; set; } + + public static byte[] SceDiskInfo => Resource.__sce_discinfo; + + private const int BLK_SIZE = 0x7C0; + + private static readonly Memory _memory = new byte[0x1000]; + + private static byte[] _psId; + + private static long _fuseId; + + public static void SetPSID(byte[] psid) + { + _psId = psid; + } + + public static void SetFuseId(long fuseId) + { + _fuseId = fuseId; + } + + public static void SetFuseId(Span fuseId) + { + SetFuseId(MemoryMarshal.Read(fuseId)); + } + + public unsafe struct SceNpDrmKey + { + private fixed byte _KeyData[16]; + public Span KeyData + { + get + { + fixed (byte* ptr = _KeyData) + { + return new Span(ptr, 16); + } + } + } + } + + [StructLayout(LayoutKind.Sequential)] + public unsafe struct Rif + { + private short _version; + private short _versionFlag; + private int _drmType; + private fixed byte _accountId[8]; + private fixed byte _contentId[0x30]; + private fixed byte _encKey1[0x10]; + private fixed byte _encKey2[0x10]; + private long _startTime; + private long _endTime; + private fixed byte _ecdsaSig[0x28]; + public short Version => _version; + public short VersionFlag => _versionFlag; + public int DrmType => _drmType; + public Span AccountId + { + get + { + fixed (byte* ptr = _accountId) + { + return new Span(ptr, 8); + } + } + } + public Span ContentId + { + get + { + fixed (byte* ptr = _contentId) + { + return new Span(ptr, 0x30); + } + } + } + public Span EncKey1 + { + get + { + fixed (byte* ptr = _encKey1) + { + return new Span(ptr, 0x10); + } + } + } + public Span EncKey2 + { + get + { + fixed (byte* ptr = _encKey2) + { + return new Span(ptr, 0x10); + } + } + } + public long StartTime => _startTime; + public long EndTime => _endTime; + + public Span EcdsaSig + { + get + { + fixed (byte* ptr = _ecdsaSig) + { + return new Span(ptr, 0x28); + } + } + } + } + + [StructLayout(LayoutKind.Sequential)] + public unsafe struct Act + { + private short _actType; + private short _versionFlag; + private int _version; + private fixed byte _accountId[8]; + private fixed byte _primKeyTable[0x800]; + private fixed byte _unk1[0x40]; + private fixed byte _openPsId[0x10]; + private fixed byte _unk2[0x10]; + private fixed byte _unk4[0x10]; + private fixed byte _secondTable[0x650]; + private fixed byte _rsaSig[0x100]; + private fixed byte _unkSig[0x40]; + private fixed byte _ecdsaSig[0x28]; + public short ActType => _actType; + public short VersionFlag => _versionFlag; + public int Version => _version; + public Span AccountId + { + get + { + fixed (byte* ptr = _accountId) + { + return new Span(ptr, 8); + } + } + } + public Span PrimKeyTable + { + get + { + fixed (byte* ptr = _primKeyTable) + { + return new Span(ptr, 0x800); + } + } + } + public Span Unk1 + { + get + { + fixed (byte* ptr = _unk1) + { + return new Span(ptr, 0x40); + } + } + } + public Span OpenPsId + { + get + { + fixed (byte* ptr = _openPsId) + { + return new Span(ptr, 0x10); + } + } + } + public Span Unk2 + { + get + { + fixed (byte* ptr = _unk2) + { + return new Span(ptr, 0x10); + } + } + } + public Span Unk4 + { + get + { + fixed (byte* ptr = _unk4) + { + return new Span(ptr, 0x10); + } + } + } + public Span SecondTable + { + get + { + fixed (byte* ptr = _secondTable) + { + return new Span(ptr, 0x650); + } + } + } + public Span RsaSig + { + get + { + fixed (byte* ptr = _rsaSig) + { + return new Span(ptr, 0x100); + } + } + } + public Span UnkSig + { + get + { + fixed (byte* ptr = _unkSig) + { + return new Span(ptr, 0x40); + } + } + } + public Span EcdsaSig + { + get + { + fixed (byte* ptr = _ecdsaSig) + { + return new Span(ptr, 0x28); + } + } + } + + } + + public static int sceNpDrmGetIDps(Span idps) + { + if (_psId != null && idps != null) + { + _psId.CopyTo(idps); + return 0; + } + return -0x7faaf6ff; + } + + private static int GetActKey(Span key, ReadOnlySpan keyTable, int count) + { + Span idps = stackalloc byte[16]; + Span decKey = stackalloc byte[16]; + int ret = sceNpDrmGetIDps(idps); + if (ret > -1) + { + ret = AesHelper.AesEncrypt(KeyVault.drmActdatKey, decKey, idps); + if (ret == 16) + { + for (int i = 0; i < count; i++) + { + ret = AesHelper.AesDecrypt(keyTable[(i * 0x10)..], key[(i * 0x10)..], decKey); + if (ret != 16) + { + ret = unchecked((int)0x80550902); + break; + } + } + ret = 0; + } + } + idps.Clear(); + decKey.Clear(); + return ret; + } + + private static int GetFreeVersionKey(Span versionKey, ReadOnlySpan rifBuf) + { + return -1; + } + + private static int GetLicenseVersionKey(Span versionKey, ReadOnlySpan actBuf, ReadOnlySpan rifBuf) + { + Span buf1 = stackalloc byte[16]; + Span buf2 = stackalloc byte[16]; + int ret = sceNpDrmVerifyAct(actBuf); + if (ret > -1) + { + ret = sceNpDrmVerifyRif(rifBuf); + if (ret > -1) + { + var act = MemoryMarshal.AsRef(actBuf); + var rif = MemoryMarshal.AsRef(rifBuf); + if (!act.AccountId.SequenceEqual(rif.AccountId)) + { + return -0x7faaf6fb; + } + if (((act.ActType & 0xff) << 8 | act.ActType >> 8) < ((rif.Version & 0xff) << 8 | rif.Version >> 9)) + { + return -0x7faaf6ef; + } + AesHelper.AesDecrypt(rif.EncKey1, buf1, KeyVault.drmRifKey); + int keyIdx = MemoryMarshal.Read(buf1[12..]); + keyIdx >>= 0x18; + if (keyIdx >= 0x80) + { + return -0x7faaf6fe; + } + ret = GetActKey(buf2, act.PrimKeyTable[(keyIdx * 0x10)..], 1); + if (ret > -1) + { + ret = AesHelper.AesDecrypt(rif.EncKey2, versionKey, buf2); + if (ret != 16) + { + ret = -0x7faaf6fe; + } + } + } + } + buf1.Clear(); + buf2.Clear(); + return ret; + } + + private static int CheckRifExpress(ReadOnlySpan rifBuf) + { + // TODO + return 0; + } + + private static int GenVersionKey(Span versionKey, int type) + { + type &= 0xffffff; + int ret = 0; + if (type != 0) + { + ret = unchecked((int)0x80550901); + if (type < 4) + { + ret = AesHelper.AesEncrypt(versionKey, versionKey, KeyVault.drmVersionKeyKey.AsSpan().Slice(type * 0x10, 0x10)); + ret = ret == 16 ? 0 : unchecked((int)0x80550902); + } + } + return ret; + } + + public static int sceNpDrmGetVersionKey(Span versionKey, ReadOnlySpan actBuf, ReadOnlySpan rifBuf, int type) + { + int ret = -0x7faaf6ff; + if (versionKey != null && rifBuf != null) + { + var rif = MemoryMarshal.AsRef(rifBuf); + if (rif.DrmType == 0x300000) + { + ret = GetFreeVersionKey(versionKey, rifBuf); + } + else + { + if (actBuf == null) + { + return ret; + } + ret = GetLicenseVersionKey(versionKey, actBuf, rifBuf); + } + if (ret > -1) + { + ret = CheckRifExpress(rifBuf); + if (ret > -1) + { + ret = GenVersionKey(versionKey, type); + } + } + } + return ret; + } + + public static int sceNpDrmGetFixedKey(Span fixedKey, ReadOnlySpan contentId, int type) + { + Span buf = stackalloc byte[0x30]; + Span mkey = stackalloc byte[48]; + int ret = -0x7faaf6ff; + if ((type & 0x1000000) != 0) + { + contentId[..0x30].CopyTo(buf); + ret = AMCTRL.sceDrmBBMacInit(mkey, 1); + if (ret == 0) + { + ret = AMCTRL.sceDrmBBMacUpdate(mkey, buf, 0x30); + if (ret == 0) + { + ret = AMCTRL.sceDrmBBMacFinal(mkey, fixedKey, KeyVault.DrmFixedKey); + if (ret == 0) + { + ret = GenVersionKey(fixedKey, (int)(type & 0xfeffffff)); + } + else + { + ret = -0x7faaf6fe; + } + } + } + } + return ret; + } + + public static int sceNpDrmGetContentKey(Span contentKey, ReadOnlySpan actBuf, ReadOnlySpan rifBuf) => sceNpDrmGetVersionKey(contentKey, actBuf, rifBuf, 0); + + public static int sceNpDrmVerifyAct(ReadOnlySpan actBuf) + { + int ret = -0x7faaf6ff; + if (actBuf != null) + { + ret = -0x7faaf6fa; + var act = MemoryMarshal.AsRef(actBuf); + if (((act.VersionFlag & 0xFF) << 8 | act.VersionFlag >> 8) < 2) + { + if (((act.ActType & 0xFF) << 8 | act.ActType >> 8) < 2) + { + ret = VerifySig(act.EcdsaSig, KeyVault.drmActRifSig, actBuf, 0x1010); + } + } + } + return ret; + } + + private static int VerifySig(ReadOnlySpan sig, ReadOnlySpan pubKey, ReadOnlySpan data, int dataSize) + { + int ret; + Span digest = stackalloc byte[32]; + if (dataSize < 0x801) + { + ret = SceDdrdb.sceDdrdbHash(data, dataSize, digest); + } + else + { + ret = (SHA1.HashData(data[..dataSize], digest) > 0 ? 0 : -1); + } + if (ret > -1) + { + ret = SceDdrdb.sceDdrdbSigvry(pubKey, digest, sig); + } + return ret; + } + + private static int FillFuseId(Span fuseId) + { + if (_fuseId != 0) + { + uint heigh = (uint)((_fuseId >> 32) & 0xffffffff); + uint low = (uint)(_fuseId & 0xffffffff); + fuseId[0] = BinaryPrimitives.ReverseEndianness(heigh); + fuseId[1] = BinaryPrimitives.ReverseEndianness(low); + } + return -1; + } + + private static int VerifyRif(ReadOnlySpan rifBuf) + { + int ret = -0x7faaf6ff; + if (rifBuf != null) + { + ret = -0x7faaf6fa; + var rif = MemoryMarshal.AsRef(rifBuf); + if (((rif.VersionFlag & 0xff) << 8 | rif.VersionFlag >> 8) < 3) + { + if (((rif.Version & 0xff) << 8 | rif.Version >> 8) < 2) + { + int ret2; + if ((rif.DrmType & 0x10000) == 0) + { + ret = VerifySig(rif.EcdsaSig, KeyVault.drmActRifSig, rifBuf, 0x70); + ret2 = -0x7faaf6fc; + } + else + { + Span buffer = stackalloc byte[0x90]; + rifBuf[..0x70].CopyTo(buffer); + if (_psId == null) + { + return ret; + } + ret = sceNpDrmGetIDps(buffer[0x70..]); + if (ret < 0) + { + return ret; + } + Span fuseId = MemoryMarshal.Cast(buffer[0x80..]); + ret = FillFuseId(fuseId); + if (ret < 0) + { + return ret; + } + ret = VerifySig(rif.EcdsaSig, KeyVault.drmActRifSig, buffer, 0x90); + ret2 = -0x7faaf6e8; + } + if (ret != 0) + { + ret = ret2; + } + } + } + } + return ret; + } + + public static int sceNpDrmVerifyRif(ReadOnlySpan rifBuf) + { + int ret = VerifyRif(rifBuf); + if (ret > -1) + { + var rif = MemoryMarshal.AsRef(rifBuf); + if (rif.DrmType == 0x3000000) + { + ret = -1; // TODO + } + } + return ret; + } + + public static int KsceNpDrmEbootSigGenMultiDisc(string fileName, ReadOnlySpan sceDiscInfo, + Span ebootSig, int swVer) + { + return SceNpDrmEbootSigGenMultiDisc(fileName, sceDiscInfo, ebootSig, swVer, _memory.Span, BLK_SIZE); + } + public static int KsceNpDrmEbootSigGenPs1(Stream file, Span ebootSig, int swVer) + { + return SceNpDrmEbootSigGen(file, 3, ebootSig, swVer, _memory.Span, BLK_SIZE); + } + + public static int KsceNpDrmEbootSigGenPsp(Stream file, Span ebootSig, int swVer) + { + return SceNpDrmEbootSigGen(file, 2, ebootSig, swVer, _memory.Span, BLK_SIZE); + } + + public static int KsceNpDrmPspEbootSigGen(Stream file, Span ebootSig) + { + return SceNpDrmPspEbootSigGen(file, ebootSig, _memory.Span, BLK_SIZE); + } + + public static int KsceNpDrmEbootSigGenPs1(string fileName, Span ebootSig, int swVer) + { + return SceNpDrmEbootSigGen(fileName, 3, ebootSig, swVer, _memory.Span, BLK_SIZE); + } + + public static int KsceNpDrmEbootSigGenPsp(string fileName, Span ebootSig, int swVer) + { + return SceNpDrmEbootSigGen(fileName, 2, ebootSig, swVer, _memory.Span, BLK_SIZE); + } + + public static int KsceNpDrmPspEbootSigGen(string fileName, Span ebootSig) + { + return SceNpDrmPspEbootSigGen(fileName, ebootSig, _memory.Span, BLK_SIZE); + } + + private static int SceNpDrmEbootSigGenMultiDisc(string fileName, ReadOnlySpan sceDiskInfo, + Span ebootSig, int swVer, Span buffer, int blockSize) + { + Span pbpHdrDigest = stackalloc byte[32]; + Span discsDigest = stackalloc byte[32]; + Span ebootSigtmp = stackalloc byte[512]; + ref var sceEbootPbp = ref MemoryMarshal.AsRef(ebootSigtmp); + if ((blockSize & 0x3F) != 0) + { + blockSize &= unchecked((int)0xFFFFFFC0); + } + + if (sceDiskInfo == null || string.IsNullOrWhiteSpace(fileName) || buffer == null || ebootSig == null || + blockSize < 0x400) + { + return unchecked((int)0x80870001); + } + + Span secureTick = stackalloc byte[8] { 0xD4, 0x7A, 0x2C, 0x13, 0x64, 0x59, 0xE2, 0x00 }; + //RandomNumberGenerator.Fill(secureTick); + + ebootSig.Fill(0); + sceEbootPbp.SwVer = swVer; + sceEbootPbp.Aid = Aid; + sceEbootPbp.SecureTick = MemoryMarshal.AsRef(secureTick); + + var sha224 = SHA224.Create(); + var hash = sha224.ComputeHash(sceDiskInfo[..200].ToArray()); + var ret = SceSblGcAuthMgrDrmBBForDriver_4B506BE7(hash, sceDiskInfo[200..], 1000); + if (ret != 0) + { + return ret; + } + + var discInfo = MemoryMarshal.AsRef(sceDiskInfo); + ret = unchecked((int)0x80870005); + if (discInfo.DiscCount > 6) + { + return ret; + } + var fi = new FileInfo(fileName); + if (!fi.Exists) + { + return -1; + } + + if (fi.Length != discInfo.FileSize) + { + return ret; + } + + ret = unchecked((int)0x80870001); + if (discInfo.DiscCount < 7) + { + if (fi.Length < discInfo.Offsets[0]) + { + return ret; + } + if (discInfo.DiscCount > 1 && fi.Length < discInfo.Offsets[1]) + { + return ret; + } + if (discInfo.DiscCount > 2 && fi.Length < discInfo.Offsets[2]) + { + return ret; + } + if (discInfo.DiscCount > 3 && fi.Length < discInfo.Offsets[3]) + { + return ret; + } + if (discInfo.DiscCount > 4 && fi.Length < discInfo.Offsets[4]) + { + return ret; + } + if (discInfo.DiscCount > 5 && fi.Length < discInfo.Offsets[5]) + { + return ret; + } + + using var stream = fi.OpenRead(); + ret = SceMultiDiscDigest(stream, fi.Length, discInfo.DiscCount, discInfo.Offsets, pbpHdrDigest, discsDigest, buffer, blockSize); + if (discInfo.DiscCount >= 0) + { + stream.Close(); + ret = SceSblGcAuthMgrDrmBBForDriver_4B506BE7(discsDigest, discInfo.DiscsSig, 1000); + if (ret != 0) + { + return ret; + } + + sceEbootPbp.PbpSize = fi.Length; + sceEbootPbp.Magic = 0x47495349544C554D; + sceEbootPbp.KeyType = 1; + sceEbootPbp.Type = 4; + discInfo.Id.CopyTo(sceEbootPbp.ContentId); + sceEbootPbp.DiscCount = discInfo.DiscCount; + discInfo.Offsets.CopyTo(sceEbootPbp.DiscOffsets); + ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(pbpHdrDigest, sceEbootPbp.PbpHdrSig, 1); + if (ret != 0) + { + return ret; + } + discInfo.DiscsSig.CopyTo(sceEbootPbp.NpUmdImgSig); + var ebootsigDigst = sha224.ComputeHash(ebootSigtmp[..0x1C8].ToArray()); + ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(ebootsigDigst, sceEbootPbp.Sig, 1); + if (ret != 0) + { + return ret; + } + ebootSigtmp.CopyTo(ebootSig); + ret = 0; + } + } + return ret; + } + + private static int SceMultiDiscDigest(Stream stream, long fileSize, int diskCount, + ReadOnlySpan diskOffsets, Span pbpHdrDigest, Span dataDigest, Span buffer, + int blockSize) + { + var sha224 = SHA224.Create(); + var ret = unchecked((int)0x80870005); + stream.Seek(0, SeekOrigin.Begin); + buffer = buffer[..blockSize]; + var readSize = stream.Read(buffer); + if (readSize < 0x28) + { + return ret; + } + var pbpHeader = MemoryMarshal.AsRef(buffer); + if (pbpHeader.Sig != 0x50425000) + { + return ret; + } + + var tmp = readSize; + if (pbpHeader.DataPsarOff < readSize) + { + tmp = pbpHeader.DataPsarOff; + } + + var paramReadSize = pbpHeader.Icon0Off; + if (paramReadSize > 0x400) + { + paramReadSize = 0x400; + } + + if (tmp < paramReadSize) + { + return ret; + } + + sha224.TransformFinalBlock(buffer.ToArray(), 0, paramReadSize); + sha224.Hash.CopyTo(pbpHdrDigest); + + sha224.Initialize(); + sha224.TransformBlock(buffer.ToArray(), 0, paramReadSize, null, 0); + + long end = pbpHeader.DataPsarOff + 0xC0000; + if (diskOffsets[0] >= pbpHeader.DataPsarOff && diskOffsets[0] < end) + { + end = diskOffsets[0]; + } + + long start = pbpHeader.DataPsarOff; + stream.Seek(start, SeekOrigin.Begin); + for (; start < end; start += readSize) + { + var toRead = (int)(end - start); + if (toRead > blockSize) + { + toRead = blockSize; + } + + readSize = stream.Read(buffer[..toRead]); + if (readSize == 0) + { + return -1; + } + sha224.TransformBlock(buffer.ToArray(), 0, readSize, null, 0); + } + + if (diskCount != 0) + { + var start1 = diskOffsets[0]; + end = diskOffsets[0] + 0xC0000; + if (end >= 0) + { + var discNo = 0; + var idx = 5; + while (true) + { + if (fileSize < end) + { + end = fileSize; + } + + if (++discNo < diskCount) + { + start = diskOffsets[idx - 4]; + if (start >= start1 && start < end) + { + end = start; + } + } + + if (start1 < end) + { + stream.Seek(start1, SeekOrigin.Begin); + while (true) + { + var toRead = (int)(end - start1); + if (toRead > blockSize) + { + toRead = blockSize; + } + + readSize = stream.Read(buffer[..toRead]); + if (readSize == 0) + { + return -1; + } + sha224.TransformBlock(buffer.ToArray(), 0, readSize, null, 0); + start1 += toRead; + if (start1 >= end) + { + break; + } + } + } + + if (discNo == diskCount) + { + break; + } + start1 = diskOffsets[idx - 4]; + idx++; + end = start1 + 0xC0000; + + } + } + } + sha224.TransformFinalBlock(buffer.ToArray(), 0, 0); + sha224.Hash.CopyTo(dataDigest); + + stream.Seek(pbpHeader.DataPsarOff, SeekOrigin.Begin); + readSize = stream.Read(buffer[..0x100]); + if (readSize == 0x100) + { + ret = 0; + } + else + { + ret = unchecked((int)0x80870005); + } + + return ret; + } + + private static int SceNpDrmEbootSigGen(string fileName, int type, Span ebootSig, int swVer, Span buffer, int blockSize) + { + if (string.IsNullOrWhiteSpace(fileName)) return -0x7f78ffff; + var fi = new FileInfo(fileName); + if (!fi.Exists) + { + return -1; + } + using (FileStream fstream = fi.OpenRead()) + { + return SceNpDrmEbootSigGen(fstream, type, ebootSig, swVer, buffer, blockSize); + } + + } + private static int SceNpDrmEbootSigGen(Stream ebootStream, int type, Span ebootSig, int swVer, Span buffer, int blockSize) + { + Span pbpHdrDigest = stackalloc byte[32]; + Span npUmdImgDigest = stackalloc byte[32]; + Span ebootSigtmp = stackalloc byte[512]; + ref var sceEbootPbp = ref MemoryMarshal.AsRef(ebootSigtmp); + if ((blockSize & 0x3F) != 0) + { + blockSize &= unchecked((int)0xFFFFFFC0); + } + + if (ebootStream == null || buffer == null || ebootSig == null || blockSize < 0x400 || type > 3) + { + return -0x7f78ffff; + } + + Span secureTick = BitConverter.GetBytes(ksceRtcGetCurrentSecureTick()); + + ebootSig.Fill(0); + sceEbootPbp.SwVer = swVer; + sceEbootPbp.Aid = Aid; + sceEbootPbp.SecureTick = MemoryMarshal.AsRef(secureTick); + + long flen = ebootStream.Length; + int ret = SceEbootPbpDigest(ebootStream, flen, pbpHdrDigest, npUmdImgDigest, buffer, blockSize); + if (ret < 0) + { + return ret; + } + + sceEbootPbp.KeyType = 1; + sceEbootPbp.PbpSize = flen; + sceEbootPbp.Type = type; + var psarSig = Encoding.ASCII.GetString(buffer[..8]); + if (type == 3) + { + if (psarSig != "PSISOIMG" && psarSig != "PSTITLEI") + { + return -0x7f78fffb; + } + sceEbootPbp.Magic = 0x474953315350504E; + } + else + { + if (psarSig != "NPUMDIMG") + { + return -0x7f78fffb; + } + + sceEbootPbp.Magic = 0x474953444D55504E; + buffer.Slice(0x10, 0x30).CopyTo(sceEbootPbp.ContentId); + } + + ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(pbpHdrDigest, sceEbootPbp.PbpHdrSig, 1); + if (ret < 0) + { + return ret; + } + + ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(npUmdImgDigest, sceEbootPbp.NpUmdImgSig, 1); + if (ret < 0) + { + return ret; + } + + var sha224 = SHA224.Create(); + var ebootsigDigst = sha224.ComputeHash(ebootSigtmp[..0x1C8].ToArray()); + ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(ebootsigDigst, sceEbootPbp.Sig, 1); + if (ret < 0) + { + return ret; + } + ebootSigtmp.CopyTo(ebootSig); + ret = 0; + return ret; + } + + private static int SceEbootPbpDigest(Stream stream, long fileSize, Span pbpHdrDigest, + Span npUmdImgDigest, Span buffer, int blockSize) + { + var sha224 = SHA224.Create(); + var ret = unchecked((int)0x80870005); + stream.Seek(0, SeekOrigin.Begin); + buffer = buffer[..blockSize]; + var readSize = stream.Read(buffer); + if (readSize < 0x28) + { + return ret; + } + + var pbpHeader = MemoryMarshal.AsRef(buffer); + if (fileSize < pbpHeader.DataPsarOff + 0xFF || pbpHeader.Sig != 0x50425000) + { + return ret; + } + + var tmp = readSize; + if (pbpHeader.DataPsarOff < readSize) + { + tmp = pbpHeader.DataPsarOff; + } + + var paramReadSize = pbpHeader.Icon0Off; + if (paramReadSize > 0x400) + { + paramReadSize = 0x400; + } + + if (tmp < paramReadSize) + { + return ret; + } + + sha224.TransformFinalBlock(buffer.ToArray(), 0, paramReadSize); + sha224.Hash.CopyTo(pbpHdrDigest); + + sha224.Initialize(); + + var alignedFileSize = (pbpHeader.DataPsarOff + 0x1C0000 + 64 - 1) & ~(64 - 1); + if (alignedFileSize < fileSize) + { + fileSize = alignedFileSize; + } + + var fixsize2 = fileSize; + if (pbpHeader.DataPsarOff + 0x1C0000 < fileSize) + { + fixsize2 = pbpHeader.DataPsarOff + 0x1C0000; + } + + if (pbpHeader.DataPsarOff < fixsize2) + { + var offset = pbpHeader.DataPsarOff; + stream.Seek(offset, SeekOrigin.Begin); + while (true) + { + readSize = stream.Read(buffer); + var bsize = readSize; + if (readSize <= 0) + { + ret = unchecked((int)0x80870002); + return ret; + } + + if (fixsize2 < offset + readSize) + { + bsize = (int)(fixsize2 - offset); + } + sha224.TransformBlock(buffer.ToArray(), 0, bsize, null, 0); + + offset += readSize; + if (offset >= fixsize2) + { + break; + } + } + sha224.TransformFinalBlock(buffer.ToArray(), 0, 0); + sha224.Hash.CopyTo(npUmdImgDigest); + stream.Seek(pbpHeader.DataPsarOff, SeekOrigin.Begin); + readSize = stream.Read(buffer[..0x100]); + if (readSize == 0x100) + { + ret = 0; + } + else + { + ret = unchecked((int)0x80870005); + } + } + + + return ret; + } + + private static int SceNpDrmPspEbootSigGen(string fileName, Span ebootSig, Span buffer, int blockSize) + { + if (string.IsNullOrWhiteSpace(fileName)) + return -0x7f78ffff; + + var fi = new FileInfo(fileName); + if (!fi.Exists) + { + return -1; + } + using (FileStream fs = fi.OpenRead()) + { + return SceNpDrmPspEbootSigGen(fs, ebootSig, buffer, blockSize); + } + } + + private static int SceNpDrmPspEbootSigGen(Stream ebootStream, Span ebootSig, Span buffer, int blockSize) + { + Span pbpHdrDigest = stackalloc byte[32]; + Span npUmdImgDigest = stackalloc byte[32]; + Span ebootSigtmp = stackalloc byte[0x100]; + ref var sceEbootPbp = ref MemoryMarshal.AsRef(ebootSigtmp); + if ((blockSize & 0x3F) != 0) + { + blockSize &= unchecked((int)0xFFFFFFC0); + } + + if (ebootStream == null || buffer == null || ebootSig == null || blockSize < 0x400) + { + return -0x7f78ffff; + } + + long fileSize = ebootStream.Length; + int ret = SceEbootPbpDigest(ebootStream, fileSize, pbpHdrDigest, npUmdImgDigest, buffer, blockSize); + if (ret < 0) + { + return ret; + } + + if (Encoding.ASCII.GetString(buffer[..8]) != "NPUMDIMG") + { + return -0x7f78fffb; + } + buffer[..0x40].CopyTo(ebootSigtmp); + sceEbootPbp.Type = 0; + sceEbootPbp.Magic = 0x474953444D55504E; + + ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(pbpHdrDigest, sceEbootPbp.PbpHdrSig, 1); + if (ret < 0) + { + return ret; + } + + ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(npUmdImgDigest, sceEbootPbp.NpUmdImgSig, 1); + if (ret < 0) + { + return ret; + } + + var sha224 = SHA224.Create(); + var ebootsigDigst = sha224.ComputeHash(ebootSigtmp[..0xC8].ToArray()); + ret = SceSblGcAuthMgrDrmBBForDriver_050DC6DF(ebootsigDigst, sceEbootPbp.Sig, 1); + if (ret < 0) + { + return ret; + } + ebootSigtmp.CopyTo(ebootSig); + ret = 0; + + return ret; + } + + private static int SceSblGcAuthMgrDrmBBForDriver_050DC6DF(ReadOnlySpan digest, Span sig, int type) + { + var curve = ECDsaHelper.SetCurve(KeyVault.Eboot_p, KeyVault.Eboot_a, KeyVault.Eboot_b, KeyVault.Eboot_N, KeyVault.Eboot_Gx, + KeyVault.Eboot_Gy); + using var ecdsa = ECDsaHelper.Create(curve, + KeyVault.Eboot_priv[type], + KeyVault.Eboot_pubx[type], + KeyVault.Eboot_puby[type], true); + var signature = ecdsa.SignHash(digest.ToArray()); + signature.CopyTo(sig); + return 0; + } + + private static ulong ksceRtcGetCurrentSecureTick() + { + DateTime epoch = new DateTime(1, 1, 1, 0, 0, 0); + DateTime now = DateTime.UtcNow; + TimeSpan ts = now.Subtract(epoch); + return Convert.ToUInt64(Math.Floor(ts.TotalMilliseconds)) * 1000; + } + + private static int SceSblGcAuthMgrDrmBBForDriver_4B506BE7(ReadOnlySpan digest, ReadOnlySpan sig, int keyType) + { + byte[] pubx; + byte[] puby; + switch (keyType) + { + case 1: + pubx = KeyVault.VitaKirk18PubKey1x; + puby = KeyVault.VitaKirk18PubKey1y; + break; + case 0: + pubx = KeyVault.VitaKirk18PubKey0x; + puby = KeyVault.VitaKirk18PubKey0y; + break; + case 1000: + pubx = KeyVault.VitaKirk18PubKey1000x; + puby = KeyVault.VitaKirk18PubKey1000y; + break; + default: + return unchecked((int)0x808a040a); + } + var curve = ECDsaHelper.SetCurve(KeyVault.Eboot_p, KeyVault.Eboot_a, KeyVault.Eboot_b, KeyVault.Eboot_N, KeyVault.Eboot_Gx, + KeyVault.Eboot_Gy); + using var ecdsa = ECDsaHelper.Create(curve, pubx, puby); + var verify = ecdsa.VerifyHash(digest.ToArray(), sig.ToArray()); + + return verify ? 0 : -1; + } + } +} diff --git a/PspCrypto/Security/Cryptography/Asn1Reader/AsnValueReader.cs b/PspCrypto/Security/Cryptography/Asn1Reader/AsnValueReader.cs deleted file mode 100644 index 85a6c9b..0000000 --- a/PspCrypto/Security/Cryptography/Asn1Reader/AsnValueReader.cs +++ /dev/null @@ -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 _span; - private readonly AsnEncodingRules _ruleSet; - - internal AsnValueReader(ReadOnlySpan 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 PeekContentBytes() - { - AsnDecoder.ReadEncodedValue( - _span, - _ruleSet, - out int contentOffset, - out int contentLength, - out _); - - return _span.Slice(contentOffset, contentLength); - } - - internal ReadOnlySpan PeekEncodedValue() - { - AsnDecoder.ReadEncodedValue(_span, _ruleSet, out _, out _, out int consumed); - return _span.Slice(0, consumed); - } - - internal ReadOnlySpan ReadEncodedValue() - { - ReadOnlySpan 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 ReadIntegerBytes(Asn1Tag? expectedTag = default) - { - ReadOnlySpan ret = AsnDecoder.ReadIntegerBytes(_span, _ruleSet, out int consumed, expectedTag); - _span = _span.Slice(consumed); - return ret; - } - - internal bool TryReadPrimitiveBitString( - out int unusedBitCount, - out ReadOnlySpan 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(Asn1Tag? expectedTag = default) where TFlagsEnum : Enum - { - TFlagsEnum ret = AsnDecoder.ReadNamedBitListValue(_span, _ruleSet, out int consumed, expectedTag); - _span = _span.Slice(consumed); - return ret; - } - - internal bool TryReadPrimitiveOctetString( - out ReadOnlySpan 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 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 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(Asn1Tag? expectedTag = null) where TEnum : Enum - { - TEnum ret = AsnDecoder.ReadEnumeratedValue(_span, _ruleSet, out int consumed, expectedTag); - _span = _span.Slice(consumed); - return ret; - } - } -} diff --git a/PspCrypto/Security/Cryptography/AsymmetricAlgorithmHelpers.cs b/PspCrypto/Security/Cryptography/AsymmetricAlgorithmHelpers.cs deleted file mode 100644 index 71a782f..0000000 --- a/PspCrypto/Security/Cryptography/AsymmetricAlgorithmHelpers.cs +++ /dev/null @@ -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[]> ReaderAsn; - - // static AsymmetricAlgorithmHelpers() - // { - // var assembly = typeof(Aes).Assembly; - // var r = assembly.GetType("System.Security.Cryptography.Asn1.AsnReader"); - // var par1Type = typeof(ReadOnlyMemory); - // 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), "rDer"); - // var sDerVar = Expression.Variable(typeof(ReadOnlyMemory), "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), rDerVar, sDerVar)); - // ReaderAsn = Expression.Lambda, ReadOnlyMemory[]>>(expBlock, par1).Compile(); - - // } - - /// - /// Convert Der format of (r, s) to Ieee1363 format - /// - public static byte[] ConvertDerToIeee1363(ReadOnlySpan 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 input, int fieldSizeBits, Span 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 rDer = sequenceReader.ReadIntegerBytes(); - ReadOnlySpan 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 signatureField, Span 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)); - } - } -} diff --git a/PspCrypto/Security/Cryptography/ECDsaManaged.cs b/PspCrypto/Security/Cryptography/ECDsaManaged.cs index ae01643..c6966ad 100644 --- a/PspCrypto/Security/Cryptography/ECDsaManaged.cs +++ b/PspCrypto/Security/Cryptography/ECDsaManaged.cs @@ -1,171 +1,170 @@ -using Org.BouncyCastle.Crypto; -using Org.BouncyCastle.Crypto.Generators; -using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Crypto.Signers; -using Org.BouncyCastle.Math; -using Org.BouncyCastle.Math.EC; -using Org.BouncyCastle.Security; -using System; - -namespace PspCrypto.Security.Cryptography -{ - internal class ECDsaManaged : System.Security.Cryptography.ECDsa - { - private ECKeyParameters _ecKeyParameters; - private readonly bool _ebootPbp; - private readonly int _type; - - public ECDsaManaged() - { - - } - - public ECDsaManaged(System.Security.Cryptography.ECParameters parameters, bool ebootPbp, int type) - { - _ebootPbp = ebootPbp; - _type = type; - var gx = new BigInteger(1, parameters.Curve.G.X); - var gy = new BigInteger(1, parameters.Curve.G.Y); - var curve = ConvertECCurve(parameters.Curve); - var g = curve.CreatePoint(gx, gy); - var domainParameters = new ECDomainParameters(curve, g, curve.Order); - if (parameters.D != null) - { - var privateKey = new BigInteger(1, parameters.D); - _ecKeyParameters = new ECPrivateKeyParameters(privateKey, domainParameters); - } - 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)); - _ecKeyParameters = new ECPublicKeyParameters(publicKey, domainParameters); - } - else - { - throw new ArgumentException("invalid parameters", nameof(parameters)); - } - } - - public override byte[] SignHash(byte[] hash) - { - if (_ecKeyParameters is not ECPrivateKeyParameters) - { - throw new ArgumentException("key is not private Key"); - } - var signer = CreateSigner(); - signer.Init(true, _ecKeyParameters); - signer.BlockUpdate(hash); - return signer.GenerateSignature(); - } - - public override bool VerifyHash(byte[] hash, byte[] signature) - { - var signer = CreateSigner(); - if (_ecKeyParameters is ECPrivateKeyParameters ecPrivateKeyParameters) - { - var publicKey = new ECPublicKeyParameters( - ecPrivateKeyParameters.Parameters.G.Multiply(ecPrivateKeyParameters.D), - ecPrivateKeyParameters.Parameters); - signer.Init(false, publicKey); - } - else - { - signer.Init(false, _ecKeyParameters); - } - signer.BlockUpdate(hash); - return signer.VerifySignature(signature); - } - - protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) - { - var dataSpan = data.AsSpan().Slice(offset, count); - if (hashAlgorithm == System.Security.Cryptography.HashAlgorithmName.SHA256) - { - return System.Security.Cryptography.SHA256.HashData(dataSpan); - } - else if (hashAlgorithm == System.Security.Cryptography.HashAlgorithmName.SHA1) - { - return System.Security.Cryptography.SHA1.HashData(dataSpan); - } - else - { - throw new NotSupportedException($"{hashAlgorithm} not supported"); - } - } - - private ISigner CreateSigner() - { - IDigest digest = DigestUtilities.GetDigest("NONE"); - IDsa dsa = _ebootPbp ? new ECDsaSigner(new EbootPbpKCalculator(_type)) : new ECDsaSigner(); - var signer = new DsaDigestSigner(dsa, digest, PlainDsaEncoding.Instance); - return signer; - } - - private FpCurve _fpCurve; - - public override void GenerateKey(System.Security.Cryptography.ECCurve curve) - { - _fpCurve = ConvertECCurve(curve); - var gx = new BigInteger(1, curve.G.X); - var gy = new BigInteger(1, curve.G.Y); - var g = _fpCurve.CreatePoint(gx, gy); - var domainParameters = new ECDomainParameters(_fpCurve, g, _fpCurve.Order); - var gen = new ECKeyPairGenerator(); - gen.Init(new ECKeyGenerationParameters(domainParameters, new SecureRandom())); - var keyPair = gen.GenerateKeyPair(); - _ecKeyParameters = (ECKeyParameters)keyPair.Private; - } - - public override System.Security.Cryptography.ECParameters ExportExplicitParameters(bool includePrivateParameters) - { - var normalG = _ecKeyParameters.Parameters.G; - var curve = new System.Security.Cryptography.ECCurve - { - A = _fpCurve.A.ToBigInteger().ToByteArrayUnsigned(), - B = _fpCurve.B.ToBigInteger().ToByteArrayUnsigned(), - Prime = _fpCurve.Q.ToByteArrayUnsigned(), - Order = _fpCurve.Order.ToByteArrayUnsigned(), - Cofactor = _fpCurve.Cofactor.ToByteArrayUnsigned(), - G = new System.Security.Cryptography.ECPoint - { - X = normalG.XCoord.ToBigInteger().ToByteArrayUnsigned(), - Y = normalG.YCoord.ToBigInteger().ToByteArrayUnsigned() - } - }; - var parameters = new System.Security.Cryptography.ECParameters - { - Curve = curve - }; - 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(); - parameters.Q = new System.Security.Cryptography.ECPoint - { - X = publicKey.XCoord.ToBigInteger().ToByteArrayUnsigned(), - Y = publicKey.YCoord.ToBigInteger().ToByteArrayUnsigned() - }; - } - else if (_ecKeyParameters is ECPublicKeyParameters publicKeyParameters) - { - var publicKey = publicKeyParameters.Q; - parameters.Q = new System.Security.Cryptography.ECPoint - { - X = publicKey.XCoord.ToBigInteger().ToByteArrayUnsigned(), - Y = publicKey.YCoord.ToBigInteger().ToByteArrayUnsigned() - }; - } - return parameters; - } - - private static FpCurve ConvertECCurve(System.Security.Cryptography.ECCurve curve) - { - var p = new BigInteger(1, curve.Prime); - var a = new BigInteger(1, curve.A); - var b = new BigInteger(1, curve.B); - var n = new BigInteger(1, curve.Order); - var fpCurve = new FpCurve(p, a, b, n, BigInteger.One); - return fpCurve; - } - } -} +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Security; +using System; + +namespace PspCrypto.Security.Cryptography +{ + internal class ECDsaManaged : System.Security.Cryptography.ECDsa + { + private ECKeyParameters _ecKeyParameters; + private readonly bool _ebootPbp; + private readonly int _type; + + public ECDsaManaged() + { + + } + + public ECDsaManaged(System.Security.Cryptography.ECParameters parameters, bool ebootPbp, int type) + { + _ebootPbp = ebootPbp; + _type = type; + var gx = new BigInteger(1, parameters.Curve.G.X); + var gy = new BigInteger(1, parameters.Curve.G.Y); + var curve = ConvertECCurve(parameters.Curve); + var g = curve.CreatePoint(gx, gy); + var domainParameters = new ECDomainParameters(curve, g, curve.Order); + if (parameters.D != null) + { + var privateKey = new BigInteger(1, parameters.D); + _ecKeyParameters = new ECPrivateKeyParameters(privateKey, domainParameters); + } + 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)); + _ecKeyParameters = new ECPublicKeyParameters(publicKey, domainParameters); + } + else + { + throw new ArgumentException("invalid parameters", nameof(parameters)); + } + } + + public override byte[] SignHash(byte[] hash) + { + if (_ecKeyParameters is not ECPrivateKeyParameters) + { + throw new ArgumentException("key is not private Key"); + } + var signer = CreateSigner(); + signer.Init(true, _ecKeyParameters); + signer.BlockUpdate(hash); + return signer.GenerateSignature(); + } + + public override bool VerifyHash(byte[] hash, byte[] signature) + { + var signer = CreateSigner(); + if (_ecKeyParameters is ECPrivateKeyParameters ecPrivateKeyParameters) + { + var publicKey = new ECPublicKeyParameters( + ecPrivateKeyParameters.Parameters.G.Multiply(ecPrivateKeyParameters.D), + ecPrivateKeyParameters.Parameters); + signer.Init(false, publicKey); + } + else + { + signer.Init(false, _ecKeyParameters); + } + signer.BlockUpdate(hash); + return signer.VerifySignature(signature); + } + + protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) + { + var dataSpan = new ReadOnlySpan(data, offset, count); + if (hashAlgorithm == System.Security.Cryptography.HashAlgorithmName.SHA256) + { + return System.Security.Cryptography.SHA256.HashData(dataSpan); + } + else if (hashAlgorithm == System.Security.Cryptography.HashAlgorithmName.SHA1) + { + return System.Security.Cryptography.SHA1.HashData(dataSpan); + } + else + { + throw new NotSupportedException($"{hashAlgorithm} not supported"); + } + } + + private ISigner CreateSigner() + { + IDigest digest = DigestUtilities.GetDigest("NONE"); + IDsa dsa = _ebootPbp ? new ECDsaSigner(new EbootPbpKCalculator(_type)) : new ECDsaSigner(); + var signer = new DsaDigestSigner(dsa, digest, PlainDsaEncoding.Instance); + return signer; + } + + private FpCurve _fpCurve; + + public override void GenerateKey(System.Security.Cryptography.ECCurve curve) + { + _fpCurve = ConvertECCurve(curve); + var gx = new BigInteger(1, curve.G.X); + var gy = new BigInteger(1, curve.G.Y); + var g = _fpCurve.CreatePoint(gx, gy); + var domainParameters = new ECDomainParameters(_fpCurve, g, _fpCurve.Order); + var gen = new ECKeyPairGenerator(); + gen.Init(new ECKeyGenerationParameters(domainParameters, new SecureRandom())); + var keyPair = gen.GenerateKeyPair(); + _ecKeyParameters = (ECKeyParameters)keyPair.Private; + } + + public override System.Security.Cryptography.ECParameters ExportExplicitParameters(bool includePrivateParameters) + { + var normalG = _ecKeyParameters.Parameters.G; + var curve = new System.Security.Cryptography.ECCurve + { + A = _fpCurve.A.ToBigInteger().ToByteArrayUnsigned(), + B = _fpCurve.B.ToBigInteger().ToByteArrayUnsigned(), + Prime = _fpCurve.Q.ToByteArrayUnsigned(), + Order = _fpCurve.Order.ToByteArrayUnsigned(), + Cofactor = _fpCurve.Cofactor.ToByteArrayUnsigned(), + G = new System.Security.Cryptography.ECPoint + { + X = normalG.AffineXCoord.ToBigInteger().ToByteArrayUnsigned(), + Y = normalG.AffineYCoord.ToBigInteger().ToByteArrayUnsigned() + } + }; + var parameters = new System.Security.Cryptography.ECParameters + { + Curve = curve + }; + if (includePrivateParameters && _ecKeyParameters is ECPrivateKeyParameters privateKeyParameters) + { + parameters.D = privateKeyParameters.D.ToByteArrayUnsigned(); + var publicKey = _ecKeyParameters.Parameters.G.Multiply(privateKeyParameters.D).Normalize(); + parameters.Q = new System.Security.Cryptography.ECPoint + { + X = publicKey.AffineXCoord.ToBigInteger().ToByteArrayUnsigned(), + Y = publicKey.AffineYCoord.ToBigInteger().ToByteArrayUnsigned() + }; + } + else if (_ecKeyParameters is ECPublicKeyParameters publicKeyParameters) + { + var publicKey = publicKeyParameters.Q.Normalize(); + parameters.Q = new System.Security.Cryptography.ECPoint + { + X = publicKey.AffineXCoord.ToBigInteger().ToByteArrayUnsigned(), + Y = publicKey.AffineYCoord.ToBigInteger().ToByteArrayUnsigned() + }; + } + return parameters; + } + + private static FpCurve ConvertECCurve(System.Security.Cryptography.ECCurve curve) + { + var p = new BigInteger(1, curve.Prime); + var a = new BigInteger(1, curve.A); + var b = new BigInteger(1, curve.B); + var n = new BigInteger(1, curve.Order); + var fpCurve = new FpCurve(p, a, b, n, BigInteger.One); + return fpCurve; + } + } +} diff --git a/PspCrypto/Security/Cryptography/EbootPbpKCalculator.cs b/PspCrypto/Security/Cryptography/EbootPbpKCalculator.cs index e7918b3..163015c 100644 --- a/PspCrypto/Security/Cryptography/EbootPbpKCalculator.cs +++ b/PspCrypto/Security/Cryptography/EbootPbpKCalculator.cs @@ -1,103 +1,103 @@ -using Org.BouncyCastle.Crypto.Digests; -using Org.BouncyCastle.Crypto.Macs; -using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Crypto.Signers; -using Org.BouncyCastle.Math; -using Org.BouncyCastle.Security; -using System; - -namespace PspCrypto.Security.Cryptography -{ - internal class EbootPbpKCalculator : IDsaKCalculator - { - private int _type; - - private BigInteger _n; - - public EbootPbpKCalculator(int type) - { - _type = type; - } - - public bool IsDeterministic => true; - - private readonly Memory _hash = new byte[0x40]; - - public void Init(BigInteger n, SecureRandom random) - { - throw new NotImplementedException(); - } - public void Init(BigInteger n, BigInteger d, byte[] message) - { - _n = n; - Span hmacIn = stackalloc byte[0x38]; - message[..0x1C].CopyTo(hmacIn); - KeyVault.Eboot_priv[_type].CopyTo(hmacIn[0x1C..]); - - var hmac = new HMac(new Sha256Digest()); - hmac.Init(new KeyParameter(KeyVault.Eboot_hmacKey)); - hmac.BlockUpdate(hmacIn); - var hmac_hash_iv = new byte[hmac.GetMacSize()]; - hmac.DoFinal(hmac_hash_iv); - - int ret; - do - { - 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) - { - throw new Exception(); - } - - } while (ret != 0); - } - - public BigInteger NextK() - { - var bn = new BigInteger(1, _hash.Span[..0x3c]); - var ret = bn.Mod(_n); - return ret; - } - - - private static int can_be_reversed_80C17A(Span src, int some_size, Span iv, - Span src_xored_digest) - { - Span src_xored = stackalloc byte[0x20]; - iv.CopyTo(src_xored); - - if (some_size > 0x20) - { - return 0x12; - } - - for (int i = 0; i < some_size; i++) - { - src_xored[i] ^= src[i]; - } - - using var sha256 = System.Security.Cryptography.SHA256.Create(); - var hash = sha256.ComputeHash(src_xored.ToArray()); - hash.CopyTo(src_xored_digest); - - for (int i = 0; i < 0x20; i++) - { - iv[i] ^= src_xored_digest[i]; - } - - for (int i = 0; i < 0x20; i++) - { - if (iv[i] != 0xFF) - { - iv[i] += 1; - break; - } - - iv[i] = 0; - } - - return 0; - } - - } -} +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using System; + +namespace PspCrypto.Security.Cryptography +{ + internal class EbootPbpKCalculator : IDsaKCalculator + { + private int _type; + + private BigInteger _n; + + public EbootPbpKCalculator(int type) + { + _type = type; + } + + public bool IsDeterministic => true; + + private readonly Memory _hash = new byte[0x40]; + + public void Init(BigInteger n, SecureRandom random) + { + throw new NotImplementedException(); + } + public void Init(BigInteger n, BigInteger d, byte[] message) + { + _n = n; + Span hmacIn = stackalloc byte[0x38]; + message[..0x1C].CopyTo(hmacIn); + KeyVault.Eboot_priv[_type].CopyTo(hmacIn[0x1C..]); + + var hmac = new HMac(new Sha256Digest()); + hmac.Init(new KeyParameter(KeyVault.Eboot_hmacKey)); + hmac.BlockUpdate(hmacIn); + var hmac_hash_iv = new byte[hmac.GetMacSize()]; + hmac.DoFinal(hmac_hash_iv); + + int ret; + do + { + 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) + { + throw new Exception(); + } + + } while (ret != 0); + } + + public BigInteger NextK() + { + var bn = new BigInteger(1, _hash.Span[..0x3c]); + var ret = bn.Mod(_n); + return ret; + } + + + private static int can_be_reversed_80C17A(Span src, int some_size, Span iv, + Span src_xored_digest) + { + Span src_xored = stackalloc byte[0x20]; + iv.CopyTo(src_xored); + + if (some_size > 0x20) + { + return 0x12; + } + + for (int i = 0; i < some_size; i++) + { + src_xored[i] ^= src[i]; + } + + using var sha256 = System.Security.Cryptography.SHA256.Create(); + var hash = sha256.ComputeHash(src_xored.ToArray()); + hash.CopyTo(src_xored_digest); + + for (int i = 0; i < 0x20; i++) + { + iv[i] ^= src_xored_digest[i]; + } + + for (int i = 0; i < 0x20; i++) + { + if (iv[i] != 0xFF) + { + iv[i] += 1; + break; + } + + iv[i] = 0; + } + + return 0; + } + + } +} diff --git a/PspCrypto/Utils.cs b/PspCrypto/Utils.cs index fecf35b..5b5581a 100644 --- a/PspCrypto/Utils.cs +++ b/PspCrypto/Utils.cs @@ -1,14 +1,11 @@ using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; - +using System.Runtime.InteropServices; + namespace PspCrypto { public static class Utils { - public static bool isEmpty(Span buf, int buf_size) + public static bool IsEmpty(Span buf, int buf_size) { if (buf != null && buf.Length >= buf_size) { @@ -21,58 +18,10 @@ namespace PspCrypto return true; } - /// - /// 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. - /// - /// - /// Supported only for platforms that support misaligned memory access or when the memory block is aligned by other means. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ref T AsRef(Span span) - where T : struct - { - if (RuntimeHelpers.IsReferenceOrContainsReferences()) - { - throw new ArgumentException( - $"Cannot use type '{typeof(T)}'. Only value types without pointers or references are supported."); - } - - if (Unsafe.SizeOf() > (uint)span.Length) - { - throw new ArgumentOutOfRangeException("length"); - } - return ref Unsafe.As(ref MemoryMarshal.GetReference(span)); - } - - /// - /// 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. - /// - /// - /// Supported only for platforms that support misaligned memory access or when the memory block is aligned by other means. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ref T AsRef(ReadOnlySpan span) - where T : struct - { - if (RuntimeHelpers.IsReferenceOrContainsReferences()) - { - throw new ArgumentException( - $"Cannot use type '{typeof(T)}'. Only value types without pointers or references are supported."); - } - - if (Unsafe.SizeOf() > (uint)span.Length) - { - throw new ArgumentOutOfRangeException("length"); - } - return ref Unsafe.As(ref MemoryMarshal.GetReference(span)); - } - public static void BuildDrmBBMacFinal2(Span mac) { Span checksum = new byte[20 + 0x10]; - ref var aesHdr = ref AsRef(checksum); + ref var aesHdr = ref MemoryMarshal.AsRef(checksum); aesHdr.mode = KIRKEngine.KIRK_MODE_ENCRYPT_CBC; aesHdr.keyseed = 0x63; aesHdr.data_size = 0x10;