Last active
June 18, 2022 12:18
-
-
Save joel16/97925b58cd37cb0d0b3e789a6145066b to your computer and use it in GitHub Desktop.
sceOpenPSIDGetProductCode impl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Structs and comments taken from uOFW's chkreg pull request #91 https://github.com/uofw/uofw/pull/91 | |
s32 sceIdStorageLookup(u16 key, u32 offset, void *pBuf, u32 len); | |
/** | |
* This structure contains console specific information. It is a subset of the ::SceConsoleId. | |
* Check <openpsid_kernel.h> for possible member values. | |
*/ | |
typedef struct { | |
/* Company code. Set to 1. */ | |
u16 companyCode; // 0 | |
/* Product code. */ | |
u16 productCode; // 2 | |
/* Product sub code. */ | |
u16 productSubCode; // 4 | |
/* Factory code. */ | |
u16 factoryCode; // 6 | |
} ScePsCode; // size = 8 | |
/** | |
* This structure represents a unique per-console identifier. It contains console specific information and can be used, | |
* for example, for DRM purposes and simple PSP hardware model checks. | |
* | |
* @remark On the PSP, Sony uses the term "PSID" (not to mixup with the term "OpenPSID" which represents a different set of | |
* unique identifier bits). On later consoles, like the PS Vita and PS4, Sony uses the term "ConsoleId" for this set of | |
* identifier bits. To be consistent within the PS family, we are going with the term "ConsoleId" here, even though APIs like | |
* sceOpenPSIDGetPSID() (which returns the ConsoleId) will remain as originally named by Sony. | |
*/ | |
typedef struct { | |
/* Unknown. On retail set to 0. */ | |
u16 unk0; // 0 | |
/* Company code. Set to 1. */ | |
u16 companyCode; // 2 | |
/* Product code. */ | |
u16 productCode; // 4 | |
/* Product sub code. */ | |
u16 productSubCode; // 6 | |
/* Upper two bit of PsFlags. */ | |
u8 psFlagsMajor : 2; // 8 | |
/* Factory code. */ | |
u8 factoryCode : 6; // 8 | |
u8 uniqueIdMajor : 2; // 9 | |
/* Lower six bit of the PsFlags. Contain the QA flag, if set. */ | |
u8 psFlagsMinor : 6; // 9 | |
u8 uniqueIdMinor[6]; // 10 | |
} SceConsoleId; // size = 16 | |
/* | |
* This structure contains the ConsoleId (termed "PSID" on the PSP) and an ECDSA signature used to verify the correctness of the | |
* ConsoleId. | |
* The ConsoleId is used, for example, in PSN DRM, DNAS and system configuration (with its derived PSCode). | |
*/ | |
typedef struct { | |
/* Unique per-console identifier. */ | |
SceConsoleId consoleId; // 0 | |
/* Contains the public key of the certificate. No padding. */ | |
u8 plantextPublicKey[0x28]; // 16 | |
/* The 'r' part of the ECDSA signature pair (r, s). */ | |
u8 r[0x14]; // 56 | |
/* The 's' part of the ECDSA signature pair (r, s). */ | |
u8 s[0x14]; // 76 | |
/* The ECDSA public key (can be used to verify ECDSA signature rs). */ | |
u8 publicKey[0x28]; // 96 | |
/* Contains the encrypted private key of the certificate (with padding). */ | |
u8 encPrivateKey[0x20]; // 136 | |
/* Hash of previous data. */ | |
u8 hash[0x10]; // 168 | |
} SceIdStorageConsoleIdCertificate; // size = 184 | |
SceUID g_semaId; //0x00004540 | |
SceIdStorageConsoleIdCertificate g_ConsoleIdCertificate; | |
// Subroutine sub_000001C4 - Address 0x000001C4 | |
s32 sceOpenPSIDLookupAndVerifyConsoleIdCertificate(void) | |
{ | |
s32 ret = 0; | |
/* Obtain a ConsoleId certificate. TODO: Use include/idstorage.h for these values once chkreg gets merged */ | |
ret = sceIdStorageLookup(0x100, 0x38, &g_ConsoleIdCertificate, KIRK_CERT_LEN); | |
if (ret < 0) { | |
ret = sceIdStorageLookup(0x120, 0x38, &g_ConsoleIdCertificate, KIRK_CERT_LEN); | |
if (ret < 0) { | |
return 0xC0520002; | |
} | |
} | |
ret = sceUtilsBufferCopyWithRange(NULL, 0, (u8 *)&g_ConsoleIdCertificate, KIRK_CERT_LEN, KIRK_CMD_CERT_VER); | |
if (ret != 0) { | |
return 0xC0520001; | |
} | |
return 0; | |
} | |
// Subroutine sceOpenPSID_B29330DE - Address 0x00000580 | |
s32 sceOpenPSIDGetProductCode(ScePsCode *pPsCode) | |
{ | |
s32 status1; | |
s32 status2; | |
status1 = 0x80000023; | |
if (pspK1StaBufOk(pPsCode, 2) >= 0) { | |
status1 = 0x80000041; | |
/* Allow only one access at a time. */ | |
status2 = sceKernelWaitSema(g_semaId, 1, NULL); | |
if (status2 == 0) { | |
if (((status1 = sceOpenPSIDLookupAndVerifyConsoleIdCertificate()) == 0)) { | |
pPsCode->productCode = g_ConsoleIdCertificate.consoleId.productCode; | |
} | |
/* Release acquired sema resource. */ | |
status2 = sceKernelSignalSema(g_semaId, 1); | |
if (status2 != 0) { | |
status1 = 0x80000041; | |
} | |
} | |
} | |
return status1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment