Put new discoveries into practice

This commit is contained in:
Li 2023-06-10 19:20:27 +12:00
parent c15e345b30
commit f087076653
18 changed files with 174 additions and 55 deletions

View File

@ -6,6 +6,10 @@ using LibChovy.VersionKey;
using System.Text;
using Vita.ContentManager;
using PspCrypto;
using Li.Utilities;
using System.Security.Cryptography;
using static PspCrypto.SceNpDrm;
using System.Runtime.InteropServices;
namespace ChovySign_CLI
{
@ -105,6 +109,7 @@ namespace ChovySign_CLI
if(rif.AccountId != accountId) { Error(rif.ContentId + " account id does not match: " + accountId.ToString("X") + " (was " + rif.AccountId.ToString("X") + ")", 10); continue; }
string[] keys = new string[4];
for (int i = 0; i < keys.Length; i++)
keys[i] = BitConverter.ToString(ActRifMethod.GetVersionKey(actDat, rif.Rif, idps, i).VersionKey).Replace("-", "");
@ -112,7 +117,7 @@ namespace ChovySign_CLI
string keysTxt = String.Join(' ', keysTxtLine);
addKeys.AppendLine(keysTxt);
Console.WriteLine(keysTxt);
//Console.WriteLine(keysTxt);
}
File.AppendAllText("KEYS.TXT", addKeys.ToString());
}
@ -143,8 +148,8 @@ namespace ChovySign_CLI
drmInfo = new NpDrmInfo(StringToByteArray(parameters[0]), parameters[1], int.Parse(parameters[2]));
break;
case ArgumentParsingMode.VERSIONKEY_EXTRACT:
if (parameters.Count != 1) return Error("--vkey-extract: expect 1 arguments. ("+parameters.Count+" given)", 4);
drmInfo = EbootPbpMethod.GetVersionKey(File.OpenRead(parameters[0]));
if (parameters.Count != 2) return Error("--vkey-extract: expect 2 arguments. ("+parameters.Count+" given)", 4);
drmInfo = EbootPbpMethod.GetVersionKey(File.OpenRead(parameters[0]), int.Parse(parameters[1]));
break;
case ArgumentParsingMode.VERSIONKEY_GENERATOR:
if(parameters.Count != 4) return Error("--vkey-gen: expect 4 arguments. ("+parameters.Count+" given)", 4);
@ -192,9 +197,58 @@ namespace ChovySign_CLI
parameters.Clear();
return 0;
}
public static void generateRif(byte[] idps, byte[] actBuf, byte[] versionKey, int versionKeyType, ulong accountId, string contentId)
{
byte[] vkey2 = new byte[versionKey.Length];
Array.Copy(versionKey, vkey2, versionKey.Length);
byte[] rkey = Rng.RandomBytes(0x10);
int keyId = 0x10; // (Int32)(Rng.RandomUInt() % 0x80);
Array.ConstrainedCopy(BitConverter.GetBytes(keyId).Reverse().ToArray(), 0, rkey, 0xC, 0x4);
byte[] encKey1 = new byte[0x10];
AesHelper.AesEncrypt(rkey, encKey1, KeyVault.drmRifKey);
// get the act key
byte[] actKey = new byte[0x10];
SceNpDrm.SetPSID(idps);
SceNpDrm.Aid = accountId;
Act act = MemoryMarshal.AsRef<Act>(actBuf);
GetActKey(actKey, act.PrimKeyTable[(keyId * 0x10)..], 1);
// reverse version key back to main version key
sceNpDrmTransformVersionKey(vkey2, versionKeyType, 0);
byte[] encKey2 = new byte[0x10];
AesHelper.AesEncrypt(vkey2, encKey2, actKey);
using (MemoryStream rifStream = new MemoryStream())
{
StreamUtil rifUtil = new StreamUtil(rifStream);
rifUtil.WriteInt16(0x0);
rifUtil.WriteInt16(0x1);
rifUtil.WriteInt32(0x2);
rifUtil.WriteUInt64(accountId);
rifUtil.WriteStrWithPadding(contentId, 0x00, 0x30);
rifUtil.WriteBytes(encKey1); // enckey1
rifUtil.WriteBytes(encKey2); // enckey2
rifUtil.WriteUInt64(SceRtc.ksceRtcGetCurrentSecureTick());
rifUtil.WriteUInt64(0x00); // expiry
rifUtil.WritePadding(0xFF, 0x28);
}
}
public static int Main(string[] args)
{
if (args.Length == 0)
{
Console.WriteLine("Chovy-Sign v2 (CLI)");
@ -211,7 +265,7 @@ namespace ChovySign_CLI
Console.WriteLine("--output-folder [output_folder]");
Console.WriteLine("--vkey [versionkey] [contentid] [key_index]");
Console.WriteLine("--vkey-extract [eboot.pbp]");
Console.WriteLine("--vkey-extract [eboot.pbp] [key_index]");
Console.WriteLine("--vkey-gen [act.dat] [license.rif] [console_id] [key_index]");
Console.WriteLine("--keys-txt-gen [act.dat] [console_id] [psp_license_folder]");

View File

@ -16,8 +16,6 @@
<None Remove="Icon.png" />
<None Remove="Popup\Global\KeySelector\ACTRIFMETHOD.PNG" />
<None Remove="Popup\Global\KeySelector\EBOOTMETHOD.PNG" />
<None Remove="Popup\Global\KeySelector\EBOOTMETHOD1.png" />
<None Remove="Popup\Global\KeySelector\EBOOTMETHOD2.png" />
<None Remove="Popup\Global\KeySelector\KEYSTXTMETHOD.PNG" />
<None Remove="PS1CD.PNG" />
<None Remove="UMD.png" />
@ -25,8 +23,7 @@
<ItemGroup>
<AvaloniaResource Include="ICON.PNG" />
<AvaloniaResource Include="Popup\Global\KeySelector\ACTRIFMETHOD.PNG" />
<AvaloniaResource Include="Popup\Global\KeySelector\EBOOTMETHOD1.PNG" />
<AvaloniaResource Include="Popup\Global\KeySelector\EBOOTMETHOD2.PNG" />
<AvaloniaResource Include="Popup\Global\KeySelector\EBOOTMETHOD.PNG" />
<AvaloniaResource Include="Popup\Global\KeySelector\KEYSTXTMETHOD.PNG" />
<AvaloniaResource Include="Ps1\PS1CD.PNG" />
<AvaloniaResource Include="Psp\UMD.PNG">

View File

@ -153,19 +153,19 @@ namespace ChovySign_GUI.Global
break;
case VersionKeyMethod.EBOOT_PBP_METHOD:
CmaBackupPicker ebootBackupSelector = new CmaBackupPicker();
ebootBackupSelector.BackupType = ((keyIndex == 1) ? "PSGAME" : "PGAME");
ebootBackupSelector.BackupType = new string[] { "PGAME", "PSGAME" };
string? gameBackupFolder = await ebootBackupSelector.ShowDialog<string>(currentWindow);
string accountId = ebootBackupSelector.AccountId;
if (gameBackupFolder is null) break;
if (accountId == "") break;
key = CMAVersionKeyHelper.GetKeyFromGamePsvimg(gameBackupFolder, accountId);
key = CMAVersionKeyHelper.GetKeyFromGamePsvimg(gameBackupFolder, accountId, this.keyIndex);
rif = CMAVersionKeyHelper.GetRifFromLicensePsvimg(gameBackupFolder, accountId);
break;
case VersionKeyMethod.KEYS_TXT_METHOD:
CmaBackupPicker pspLicenseBackupSelector = new CmaBackupPicker();
pspLicenseBackupSelector.BackupType = "PGAME";
pspLicenseBackupSelector.BackupType = new string[] { "PGAME", "PSGAME" };
pspLicenseBackupSelector.Filter = KeysTxtMethod.TitleIds;
gameBackupFolder = await pspLicenseBackupSelector.ShowDialog<string>(currentWindow);
@ -186,10 +186,8 @@ namespace ChovySign_GUI.Global
if (key is not null)
{
if (key.KeyIndex != this.keyIndex)
{
await MessageBox.Show(currentWindow, "VersionKey obtained, but had keyindex: " + key.KeyIndex + " however keyindex " + this.keyIndex + " was required.", "KeyIndex mismatch!", MessageBoxButtons.Ok);
return;
}
sceNpDrmTransformVersionKey(key.VersionKey, key.KeyIndex, this.keyIndex);
// its a revoolution~
VersionKey = key.VersionKey;
}

View File

@ -3,7 +3,8 @@ using Avalonia.Interactivity;
using ChovySign_GUI.Global;
using GameBuilder.Psp;
using LibChovy.Config;
using Org.BouncyCastle.Utilities.Bzip2;
using Org.BouncyCastle.Asn1;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -16,7 +17,7 @@ namespace ChovySign_GUI.Popup.Global
private const string lookingInLabelText = "Looking in: ";
private string[]? gameDirectories;
private string backupSubFolder = "";
private string[] backupSubFolders;
private string[]? filter;
@ -69,50 +70,80 @@ namespace ChovySign_GUI.Popup.Global
}
}
private string accountIdSearchFolder
private string[] accountIdSearchFolders
{
get
{
string searchIn = Path.Combine(BackupDir, this.BackupType);
string[] searchIn = new string[this.BackupType.Length];
for (int i = 0; i < this.BackupType.Length; i++)
{
searchIn[i] = Path.Combine(BackupDir, this.BackupType[i]);
}
return searchIn;
}
}
private string backupSearchFolder
private string[] backupSearchFolders
{
get
{
if (AccountId == "") return accountIdSearchFolder;
return Path.Combine(accountIdSearchFolder, AccountId);
string[] backupFolders = new string[this.BackupType.Length];
string[] searchFolders = this.accountIdSearchFolders;
for (int i = 0; i < this.BackupType.Length; i++)
{
if (this.AccountId == "") backupFolders[i] = searchFolders[i];
backupFolders[i] = Path.Combine(searchFolders[i], this.AccountId);
}
return backupFolders;
}
}
public string BackupType
public string[] BackupType
{
get
{
return backupSubFolder;
return backupSubFolders;
}
set
{
backupSubFolder = value;
lookingInLbl.Content = lookingInLabelText + backupSubFolder;
backupSubFolders = value;
lookingInLbl.Content = lookingInLabelText + String.Join(", ", backupSubFolders);
reloadAccountIdsList();
reloadBackupsList();
}
}
private string[] GetAllDriectories(string[] dirList)
{
List<string> foundDir = new List<string>();
foreach(string dirSearch in dirList)
{
if (!Directory.Exists(dirSearch)) continue;
foreach(string dir in Directory.GetDirectories(dirSearch))
{
if (!foundDir.Contains(dir))
{
foundDir.Add(dir);
}
}
}
return foundDir.ToArray();
}
private void reloadAccountIdsList()
{
try
{
string[] usedAccountIds = Directory.GetDirectories(accountIdSearchFolder);
string[] usedAccountIds = GetAllDriectories(accountIdSearchFolders);
List<string> accountIdLst = new List<string>();
foreach (string accountId in usedAccountIds)
{
string aid = Path.GetFileName(accountId);
if (accountIdLst.Contains(aid)) continue;
if (aid.Length != 16) continue;
accountIdLst.Add(aid);
}
this.accId.Items = accountIdLst.ToArray();
@ -142,8 +173,8 @@ namespace ChovySign_GUI.Popup.Global
this.backupList.Items = new string[0];
try
{
if(!Directory.Exists(backupSearchFolder)) { return; }
string[] gameBackupDirectories = Directory.GetDirectories(backupSearchFolder);
string[] gameBackupDirectories = GetAllDriectories(backupSearchFolders);
List<string> filteredGameDirectories = new List<string>();
List<string> gameList = new List<string>();
foreach (string gameDirectory in gameBackupDirectories)
@ -180,7 +211,7 @@ namespace ChovySign_GUI.Popup.Global
{
InitializeComponent();
this.cmaDir.FilePath = BackupDir;
this.backupSubFolder = "APP";
this.backupSubFolders = new string[] { "APP" };
this.accId.SelectionChanged += onAccountSelectionChanged;
this.cmaDir.FileChanged += onCmaDirChanged;
this.backupList.SelectionChanged += onSelectedBackupChanged;
@ -191,6 +222,7 @@ namespace ChovySign_GUI.Popup.Global
private void onSelectedBackupChanged(object? sender, SelectionChangedEventArgs e)
{
ListBox? lstBox = sender as ListBox;
if (lstBox is null) return;
if (lstBox.SelectedIndex == -1) selectBtn.IsEnabled = false;
else selectBtn.IsEnabled = true;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

View File

@ -21,8 +21,7 @@
<Button Content="IDPS+RIF+ACT Method" Click="actRifMethodClick" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button Content="KEYS.TXT Method" Click="keysTxtMethodClick" Grid.Row="0" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Image Name="ebootMethodPs1Graphic" Source="/Popup/Global/KeySelector/EBOOTMETHOD1.PNG" Grid.Row="1" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
<Image Name="ebootMethodPspGraphic" Source="/Popup/Global/KeySelector/EBOOTMETHOD2.PNG" Grid.Row="1" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
<Image Name="ebootMethodGraphic" Source="/Popup/Global/KeySelector/EBOOTMETHOD.PNG" Grid.Row="1" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
<Image Name="actRifMethodGraphic" Source="/Popup/Global/KeySelector/ACTRIFMETHOD.PNG" Grid.Row="1" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
<Image Name="keysTxtMethodGraphic" Source="/Popup/Global/KeySelector/KEYSTXTMETHOD.PNG" Grid.Row="1" Grid.Column="2" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
</Grid>

View File

@ -20,8 +20,6 @@ namespace ChovySign_GUI.Popup.Global.KeySelector
set
{
keyIndex = value;
if (keyIndex == 1) { ebootMethodPspGraphic.IsVisible = false; ebootMethodPs1Graphic.IsVisible = true; }
else { ebootMethodPspGraphic.IsVisible = true; ebootMethodPs1Graphic.IsVisible = false; }
}
}

View File

@ -117,6 +117,10 @@ namespace Li.Utilities
{
WriteBytesWithPadding(Encoding.UTF8.GetBytes(str), b, len);
}
public void WriteUInt64(UInt64 v)
{
WriteBytes(BitConverter.GetBytes(v));
}
public void WriteInt64(Int64 v)
{
WriteBytes(BitConverter.GetBytes(v));

View File

@ -137,3 +137,17 @@ EP9000-UCES01242_00-PRESELLADDONPCK0 FE1E0A3B419BB9376D084ABEC54A526B DBD40050D8
EP9000-UCES01242_00-PRESELLADDONPCK1 45331A2B5F214CD4E1297227126FAE95 FC1310D9604F5DC4FFF1015299A33524 A46821B0D75A1EA5932A9C6E6CC41E9B 70C67F9198F5105DFE70AA867679E0D3
EP9000-UCES01242_00-PRESELLADDONPCK3 3C67064205AF3B6F5516E1008F7E9578 3DA0A4525880F6E65D921B406291D0E0 FDB5E4B9E8FE2EBED8BE487F8B585ED9 C07F639AC4C4E5E3E3DED4054F600514
EP9000-UCES01242_00-PRESELLADDONPCK2 211625C7ACF3AD87FB80C088B5A816D0 731870DDA5D2B6A454FC32B196B39BB4 034B72CB73F41ECE183E17C5F1F5DB2F 01BDE1B45251E03597DE2D00F745E0E0
EP0001-NPEH00029_00-GPCASSASSINPGO02 3256531B6287569F75A12C24DB1D92F5 779E4C9FA20A2DC30DBBFDC05B6F8CE9 0E446F48989AF17569671B0BC24EE951 CBFD89B5ED02344EC13485B31E32DAB1
EP0006-NPEW00073_00-TPCFIFA11P000001 266993E225B9FE02F6784CF706624989 F19D7EDF0BDC5889A96DACB9B8D1AC68 C12E67459716BACCC208707B65793E1D 5C2104AB3DDB9974E444259EA0C75C2A
EP1004-ULES00502_00-GPCGRANDTH000001 0E39CF82632FFF40CB6431ED3D612C55 80C952D1EAE9B0486080B9A34E0F7C26 FD1233140909948C810391716D4730C9 9A1B891F7885430FBF0E2AD3B1AA15EE
EP1063-NPEH00101_00-PRAM001122334455 30CDDC33A4E18D8C9335278B7E05BB9B 4A1FBE67782A0324E4C7756F3854FE2B 60C5698A260CD64F8EF4ABFC936A354F D46F9CFBC83E2BCAE3C0AEB44D678756
EP1063-NPEH00101_00-TICKET0011223344 891C6358BCD5FA5822125170C9CFDC88 67128C1321601EB91F7FCF0D643A5A83 C0713C15C91ABF06278CC0A9437F1F27 53FAB2836B5DC5C89A2CC9D68CE5C23E
EP4293-ULES01515_00-GBPSPGAMERG00100 2CD73C4EFC809558543F1B3E3C272AB9 64794493FD2B4B960FB73AD6B1E140F7 766898B4E6BD91A138C242B4D56B1EE1 E849705F7C20FA3E4A963A01A632B8AA
EP9000-NPEG90013_00-DPCRESISTA000001 D9621D80C5BEF35B42DC2A18E8C1C1F2 D27AC3D28A9D564F8EE713B1C485C1B7 9BBB0AD3A6BDA78720ADBC73E30018BD 4EEE59B99F8DD06D97DFF7E196B317C0
EP9000-NPEG90019_00-LBPPSPEPSN000001 C0F7AD7D7012202CF27BBE670265BF05 1DCF8692689FB9CC0E010DE98EF77C23 8957E078A33C249D6CFEBF4A69CD21EE 6ADCB170B8A861E2035BAA20CB5BAA2C
EP9000-NPEW00068_00-TPCPSPGOPR000001 C3602E7EE9CA1B5D4600C5AA54BB1055 B53C53352F887C2DA84E5BDE29EB72AF 8CFA5E61BE013AFCFE418126CEF4D809 36644FDB1346637D6AF6C21426692FB8
EP9000-UCED90042_00-DPCSOCOMFTDEMO01 47D6208DF789C4ECD86692CF4D60A322 ECA7BAEC11B35B8F54280FE0D389B3B6 78DA407B23310875D52648802F7E4974 1878AC0652D24B8AEFB286358D2B5E60
EP9000-UCES00422_00-RIDGERACER2DEMO1 D5041BB4CBFBDFD6470F9F9EE6FE5A12 8A9833DB42B4848FEA6BF46E0CCCBB6D F09D093506D205CAE121D641C0AAB354 33B9BB2EE725BF8AD6AED826447C6BE9
EP9000-UCES00694_00-PFXTRMJUSTPSPGO2 0A4368759887952E157998EA5EA27396 71539E955A231AA6AB7044DA6E3D80AD FCCFB57EA5C15E1E5554811ECC7203E3 3041033FCD90D2ABA50545F6227410EB
EP9000-UCES01264_00-LBPPSPEFULL00001 297DBC7870E72EF195D85611A10B94E7 A9F0F0D181C264D15CB3AFC553EB63A7 0D905696883327C8F4CE4DC45B185FB8 900132071EB7175615C1CA822C804BA0
EP9001-NPEW00051_00-TPCGRANTUR000001 FEA1848910E05C9D45C9FBFA8863C1BE DE374F786E6CBF4E057B1C9EB64B3124 D50C141C8A7B0B840903F60A3796FB5B A346DCD09D173B36E524B29D776066C3

View File

@ -26,7 +26,7 @@ namespace LibChovy.VersionKey
catch { return null; }
}
public static NpDrmInfo? GetKeyFromGamePsvimg(string gameBackupFolder, string accountId)
public static NpDrmInfo? GetKeyFromGamePsvimg(string gameBackupFolder, string accountId, int keyIndex)
{
string gamePsvimgFile = Path.Combine(gameBackupFolder, "game", "game.psvimg");
if (!File.Exists(gamePsvimgFile)) return null;
@ -36,7 +36,7 @@ namespace LibChovy.VersionKey
using (PSVIMGFileStream? pbp = GetFileFromPsvImg(gamePsvimgFile, "/EBOOT.PBP", cmaKey))
{
if (pbp is null) return null;
return EbootPbpMethod.GetVersionKey(pbp);
return EbootPbpMethod.GetVersionKey(pbp, keyIndex);
}
}

View File

@ -21,7 +21,7 @@ namespace LibChovy.VersionKey
AMCTRL.bbmac_getkey(mkey, bbmac, versionKey);
return versionKey;
}
public static NpDrmInfo GetVersionKey(Stream ebootStream)
public static NpDrmInfo GetVersionKey(Stream ebootStream, int keyIndex)
{
using (ebootStream)
{
@ -39,32 +39,35 @@ namespace LibChovy.VersionKey
switch (psarMagic)
{
case "NPUMDIMG":
int keyType = ebootUtil.ReadInt32();
int orginalKeyIndex = ebootUtil.ReadInt32();
string contentId = ebootUtil.ReadStringAt(dataPsarLocation + 0x10);
byte[] npUmdHdr = ebootUtil.ReadBytesAt(dataPsarLocation, 0xC0);
byte[] npUmdHeaderHash = ebootUtil.ReadBytesAt(dataPsarLocation + 0xC0, 0x10);
byte[] versionkey = getKey(npUmdHeaderHash, npUmdHdr);
return new NpDrmInfo(versionkey, contentId, keyType);
SceNpDrm.sceNpDrmTransformVersionKey(versionkey, orginalKeyIndex, keyIndex);
return new NpDrmInfo(versionkey, contentId, keyIndex);
case "PSISOIMG":
using (DNASStream dnas = new DNASStream(ebootStream, dataPsarLocation + 0x400))
{
contentId = ebootUtil.ReadStringAt(dataPspLocation + 0x560);
keyType = dnas.KeyIndex;
orginalKeyIndex = dnas.KeyIndex;
versionkey = dnas.VersionKey;
return new NpDrmInfo(versionkey, contentId, keyType);
SceNpDrm.sceNpDrmTransformVersionKey(versionkey, orginalKeyIndex, keyIndex);
return new NpDrmInfo(versionkey, contentId, keyIndex);
}
case "PSTITLEI":
using (DNASStream dnas = new DNASStream(ebootStream, dataPsarLocation + 0x200))
{
contentId = ebootUtil.ReadStringAt(dataPspLocation + 0x560);
keyType = dnas.KeyIndex;
orginalKeyIndex = dnas.KeyIndex;
versionkey = dnas.VersionKey;
return new NpDrmInfo(versionkey, contentId, keyType);
SceNpDrm.sceNpDrmTransformVersionKey(versionkey, orginalKeyIndex, keyIndex);
return new NpDrmInfo(versionkey, contentId, keyIndex);
}
default:
throw new Exception("Cannot obtain versionkey from this EBOOT.PBP (magic:" + psarMagic + ")");

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 96 KiB

View File

@ -197,6 +197,7 @@ namespace PspCrypto
var encData = encryptor.TransformFinalBlock(buffer, 0, buffer.Length);
encData.AsSpan().CopyTo(oubput);
}
#if false
public static byte[] AesDecrypt(Aes aes, byte[] data, int offset, int length)
{

View File

@ -1080,7 +1080,7 @@ namespace PspCrypto
unsafe
{
var ecdsa = ECDsaHelper.Create(curve, sig.public_key.x, sig.public_key.y);
ECDsa ecdsa = ECDsaHelper.Create(curve, sig.public_key.x, sig.public_key.y);
if (ecdsa.VerifyHash(sig.message_hash, sig.signature.sig))
{

View File

@ -3,6 +3,7 @@ using System;
using System.Buffers.Binary;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
@ -433,6 +434,14 @@ namespace PspCrypto
}
}
public static int sceNpDrmTransformVersionKey(Span<byte> versionKey, int srcKeyType, int dstKeyType)
{
// reverse the previous "GenVersionKey" step ..
int ret = ReverseGenVersionKey(versionKey, srcKeyType);
if (ret >= 0)
ret = GenVersionKey(versionKey, dstKeyType); // generate a new version key of this type
return ret;
}
public static int sceNpDrmGetIDps(Span<byte> idps)
{
@ -444,7 +453,7 @@ namespace PspCrypto
return -0x7faaf6ff;
}
private static int GetActKey(Span<byte> key, ReadOnlySpan<byte> keyTable, int count)
public static int GetActKey(Span<byte> key, ReadOnlySpan<byte> keyTable, int count)
{
Span<byte> idps = stackalloc byte[16];
Span<byte> decKey = stackalloc byte[16];
@ -525,6 +534,22 @@ namespace PspCrypto
return 0;
}
private static int ReverseGenVersionKey(Span<byte> versionkey, int type)
{
type &= 0xffffff;
int ret = 0;
if (type != 0)
{
ret = unchecked((int)0x80550901);
if (type < 4)
{
ret = AesHelper.AesDecrypt(versionkey, versionkey, KeyVault.drmVersionKeyKey.AsSpan().Slice(type * 0x10, 0x10));
ret = ret == 16 ? 0 : unchecked((int)0x80550902);
}
}
return ret;
}
private static int GenVersionKey(Span<byte> versionKey, int type)
{
type &= 0xffffff;

View File

@ -11,16 +11,10 @@ atleast one of these are free in *most* regions;
however failing that, you can also use a PSP DLC license-
-- if you don't have a hacked PSVita:
Note: If the game you are using to do this with any games besides PETZ SADDLE CLUB, LOCOROCO MIDNIGHT CARNIVAL or APE QUEST STARTER PACK;
you will be limited to the same game type as the license is for,
i.e a PS1 game will only be usable to create a PS1 game,
and a PSP game will only be usable to create a PSP game
(this is different' if you use the henkaku method)
Copy the game to your PC using Content Manager,
open chovy-sign2 and click the "Get Keys" button
-- if you are using "APE QUEST, LOCOROCO MIDNIGHT CARNIVAL, or PETZ SADDLE CLUB, and want to make a PS1 game select "KEYS.TXT" instead-)
select "EBOOT.PBP" method, click on the game
(note: there may be some issues if you try this while having DLC for the game installed ...)
you should see the RIF and KEY fields populate, and your good to go!