SceSblGcAuthMgr: Difference between revisions
CelesteBlue (talk | contribs) |
CelesteBlue (talk | contribs) No edit summary |
||
Line 410: | Line 410: | ||
| 0.990 || 0x46B7AA5A | | 0.990 || 0x46B7AA5A | ||
|} | |} | ||
Calls get_aes_dec_key. | |||
<source lang="C"> | |||
typedef struct ScePcactActivationData { // size is 0x1090 on FW 0.990 | |||
char unk_buf[0x50]; | |||
char act_data[0x1040]; | |||
} ScePcactActivationData; | |||
int sceSblGcAuthMgrPcactActivationForDriver(const ScePcactActivationData *act_data, SceSize act_data_size);</source> | |||
=== sceSblGcAuthMgrPcactGetChallengeForDriver === | === sceSblGcAuthMgrPcactGetChallengeForDriver === | ||
Line 421: | Line 431: | ||
Calls SceSblGcAuthMgrPcactForDriver_B7AE58B9. | Calls SceSblGcAuthMgrPcactForDriver_B7AE58B9. | ||
<source lang="C">int sceSblGcAuthMgrPcactGetChallengeForDriver(SceUID id, const char *entropy, char *challenge);</source> | <source lang="C"> | ||
// entropy size is 0x20 bytes | |||
// challenge size is 0x80 bytes | |||
int sceSblGcAuthMgrPcactGetChallengeForDriver(SceUID id, const char *entropy, char *challenge); | |||
</source> | |||
=== SceSblGcAuthMgrPcactForDriver_B7AE58B9 === | === SceSblGcAuthMgrPcactForDriver_B7AE58B9 === | ||
Line 431: | Line 445: | ||
|} | |} | ||
<source lang="C">int SceSblGcAuthMgrPcactForDriver_B7AE58B9(SceUID id, uint a2, uint a3, char *challenge, void * | <source lang="C"> | ||
// challenge size is 0x80 bytes | |||
// buf_40 size is 0x40 bytes | |||
int SceSblGcAuthMgrPcactForDriver_B7AE58B9(SceUID id, uint a2, uint a3, char *challenge, void *buf_40); | |||
</source> | |||
=== | === get_aes_dec_key === | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
Line 440: | Line 458: | ||
| 0.990 || 0xCA97CE1C | | 0.990 || 0xCA97CE1C | ||
|} | |} | ||
<source lang="C"> | |||
// act_data size is 0x1040 bytes | |||
// buf_40 size is 0x40 bytes | |||
// aes_dec_key_size is 0x20 bytes | |||
int get_aes_dec_key(const char *act_data, void *buf_40, void *aes_dec_key); | |||
</source> | |||
== SceSblGcAuthMgrMlnpsnlForDriver == | == SceSblGcAuthMgrMlnpsnlForDriver == | ||
Line 461: | Line 486: | ||
== SceSblGcAuthMgrPkgForDriver == | == SceSblGcAuthMgrPkgForDriver == | ||
=== | === sceSblGcAuthMgrPkgVryForDriver === | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Version !! NID | ! Version !! NID | ||
|- | |- | ||
| 3.60 || 0xE459A9A8 | | 0.990-3.60 || 0xE459A9A8 | ||
|} | |} | ||
Calls [[F00D_Commands#0x11_kirk_ecc160_verify KIRK command 0x11]] to verify PKG ECDSA signature. | |||
<source lang="C"> | |||
// sha1 size is 0x14 bytes | |||
// ecc_sig size is 28 bytes (2 * 0x14 bytes) | |||
int sceSblGcAuthMgrPkgVryForDriver(const char *sha1, const char *ecc_sig); | |||
</source> | |||
== SceSblGcAuthMgrSclkForDriver == | == SceSblGcAuthMgrSclkForDriver == |
Revision as of 21:41, 2 February 2020
Secure bootloader Gamecard Auth Manager
Module
Known NIDs
Version | Name | World | Privilege | NID |
---|---|---|---|---|
1.69 | SceSblGcAuthMgr | Non-secure | Kernel | 0x4B777EBC |
3.60 | SceSblGcAuthMgr | Non-secure | Kernel | 0xDB1A9016 |
Libraries
Known NIDs
Version | Name | World | Visibility | NID |
---|---|---|---|---|
1.69 | SceSblGcAuthMgrDrmBBForDriver | Non-secure | Kernel | 0x1926B182 |
3.60 | SceSblGcAuthMgrDrmBBForDriver | Non-secure | Kernel | 0x1926B182 |
1.69 | SceSblGcAuthMgrPcactForDriver | Non-secure | Kernel | 0x0B8600A5 |
3.60 | SceSblGcAuthMgrPcactForDriver | Non-secure | Kernel | NOT PRESENT |
1.69 | SceSblGcAuthMgrMlnpsnlForDriver | Non-secure | Kernel | 0x29ED0109 |
3.60 | SceSblGcAuthMgrMlnpsnlForDriver | Non-secure | Kernel | 0x29ED0109 |
1.69 | SceSblGcAuthMgrAdhocBBForDriver | Non-secure | Kernel | 0x2EFA9203 |
3.60 | SceSblGcAuthMgrAdhocBBForDriver | Non-secure | Kernel | NOT PRESENT |
1.69 | SceSblGcAuthMgrPkgForDriver | Non-secure | Kernel | 0x082FBA7D |
3.60 | SceSblGcAuthMgrPkgForDriver | Non-secure | Kernel | 0x082FBA7D |
1.69 | SceSblGcAuthMgrSclkForDriver | Non-secure | Kernel | 0xF24F760D |
3.60 | SceSblGcAuthMgrSclkForDriver | Non-secure | Kernel | 0xF24F760D |
1.69 | SceSblGcAuthMgrGcAuthForDriver | Non-secure | Kernel | 0xC6627F5E |
3.60 | SceSblGcAuthMgrGcAuthForDriver | Non-secure | Kernel | 0xC6627F5E |
1.69 | SceSblGcAuthMgr | Non-secure | User | 0x7B13BCF7 |
3.60 | SceSblGcAuthMgr | Non-secure | User | 0x7B13BCF7 |
3.60 | SceSblGcAuthMgrPsmactForDriver | Non-secure | Kernel | 0x1C53F37D |
3.60 | SceSblGcAuthMgrMsSaveBBForDriver | Non-secure | Kernel | 0x5032E8D4 |
Data segment layout
Address | Size | Description |
---|---|---|
0x0000 | 0x4BC4 | unknown |
0x4BC4 | 0x30 | temp buffer for storing parts of cmd56 packets |
0x4BF4 | 0x200 | cmd56 request buffer |
0x4DF4 | 0x04 | packet6 gc parameter |
0x4DF8 | 0x200 | temp buffer for initializing cm56 req packets |
0x4FF8 | 0x20 | temp buffer for storing parts of cmd56 packets |
0x5018 | 0x34 | one of kirk responses |
0x504C | 0x200 | cmd56 response buffer 1 |
0x524C | 0x200 | cmd56 response buffer 2 |
0x544C | 0x20 | one of kirk responses |
0x546C | 0x898 | unknown |
SceSblGcAuthMgrDrmBBForDriver
command 0x1000B 0x11
Version | NID |
---|---|
3.60 | 0x4CEA150C |
Original PSP Kirk 0x11 service for 160bit ECC signature verification.
command 0x1000B 0x18
Version | NID |
---|---|
3.60 | 0x4B506BE7 |
Almost certainly a 224bit version of 0x11
command 0x1000B 0x21
Version | NID |
---|---|
3.60 | 0x30A0B441 |
command 0x1000B 0x22
Version | NID |
---|---|
3.60 | 0x050DC6DF |
command 0x1000B 0x4
Version | NID |
---|---|
3.60 | 0x500F5157 |
Original PSP Kirk 4 service for encrypting data
command 0x1000B 0x4
Version | NID |
---|---|
3.60 | 0x6EF3C9DB |
Original PSP Kirk 4 service for encrypting data
command 0x1000B 0x4
Version | NID |
---|---|
3.60 | 0x7F98E4E2 |
Original PSP Kirk 4 service for encrypting data
command 0x1000B 0x4
Version | NID |
---|---|
3.60 | 0xE950BE32 |
Original PSP Kirk 4 service for encrypting data
command 0x1000B 0x7
Version | NID |
---|---|
3.60 | 0x3C25F9FA |
Original PSP Kirk 7 service for decrypting data
command 0x1000B 0x7
Version | NID |
---|---|
3.60 | 0xB13577E2 |
Original PSP Kirk 7 service for decrypting data
command 0x1000B 0x7
Version | NID |
---|---|
3.60 | 0xC0F37F18 |
Original PSP Kirk 7 service for decrypting data
command 0x1000B 0x4 0x7
Version | NID |
---|---|
3.60 | 0x4FE89ADB |
Original PSP Kirk Enc and Dec
int unk_4FE89ADB(int unk0, int unk1, int unk2, int unk3, int arg_0);
clear_context
Version | NID |
---|---|
3.60 | 0x48D7784E |
typedef struct ctx_48D7784E //size is 0x28 { uint32_t unk_0; char unk_4[0x10]; char unk_14[0x10]; uint32_t unk_24; }ctx_48D7784E; int clear_context(ctx_48D7784E *ctx, int idx);
clear_context
Version | NID |
---|---|
3.60 | 0x6E6D2B89 |
typedef struct ctx_6E6D2B89 //size is 0x18 { uint32_t unk_0; uint32_t unk_4; char unk_8[0x10]; }ctx_6E6D2B89; int clear_context(ctx_6E6D2B89 *ctx);
enc_dec
Version | NID |
---|---|
3.60 | 0x4C5DE1AA |
Includes both aes and psp kirk 0x1000B 4 and 7
int enc_dec(void* data, void* dec_rif_key, int unk2, void* unk3);
error
Version | NID |
---|---|
3.60 | 0x535B87BC |
Returns error 0x808A040A.
get_5018_data
Version | NID |
---|---|
3.60 | 0xBB70DDC0 |
This function copies first 0x20 bytes of the buffer of size 0x34 to destination.
Buffer is obtained with KIRK command 0x20.
int get_5018_data(char* dest);
memcmp_5018_fast
Version | NID |
---|---|
3.60 | 0x22FD5D23 |
This function verifies that last 0x14 bytes of last response of size 0x34 from the game card (cmd56) are valid
CMD56 response is obtained with Buffer is obtained with KIRK command 0x20
For example it is called from sceAppMgrGameDataMount
int memcmp_5018_fast(char* in_data);
This is a timing safe memcmp. Xyz (talk) 10:02, 1 May 2017 (UTC)
clear_sensitive_data
Version | NID |
---|---|
3.60 | 0x812B2B5C |
Clears some sensitive data.
Called after verify_checksum
.
int clear_sensitive_data(int unk, int* value);
clear_sensitive_data
Version | NID |
---|---|
3.60 | 0xBB451E83 |
Clears sensitive data that is left after cmd56 custom initialization.
This includes data generated by Kirk services 0x1C, 0x1F, 0x20 and packet6.
Buffer offsets are 0x4BC4, 0x4FF8, 0x5018, 0x544C.
Called after initialize_sd_device
.
int clear_sensitive_data();
SceSblGcAuthMgrAdhocBBForDriver
Present on 1.69. Not present on 3.60+.
sceSblGcAuthMgrAdhocBB224InitForDriver
Version | NID |
---|---|
0.940 | 0xAD28D0FC |
sceSblGcAuthMgrAdhocBB224ShutdownForDriver
Version | NID |
---|---|
0.940 | 0xF373E805 |
sceSblGcAuthMgrAdhocBB224GetKeysForDriver
Version | NID |
---|---|
0.940 | 0x8558BE2C |
sceSblGcAuthMgrAdhocBB224Auth1ForDriver
Version | NID |
---|---|
0.940 | 0x0FD3C103 |
sceSblGcAuthMgrAdhocBB224Auth2ForDriver
Version | NID |
---|---|
0.940 | 0xCBC471F2 |
sceSblGcAuthMgrAdhocBB224Auth3ForDriver
Version | NID |
---|---|
0.940 | 0x772914E5 |
sceSblGcAuthMgrAdhocBB224Auth4ForDriver
Version | NID |
---|---|
0.940 | 0x7EDBBBF8 |
sceSblGcAuthMgrAdhocBB224Auth5ForDriver
Version | NID |
---|---|
0.940 | 0x79DD1A5E |
SceSblGcAuthMgrPcactForDriver
Present on 0.990-1.69. Not present on 3.60+.
sceSblGcAuthMgrPcactActivationForDriver
Version | NID |
---|---|
0.990 | 0x46B7AA5A |
Calls get_aes_dec_key.
typedef struct ScePcactActivationData { // size is 0x1090 on FW 0.990 char unk_buf[0x50]; char act_data[0x1040]; } ScePcactActivationData; int sceSblGcAuthMgrPcactActivationForDriver(const ScePcactActivationData *act_data, SceSize act_data_size);
sceSblGcAuthMgrPcactGetChallengeForDriver
Version | NID |
---|---|
0.990 | 0xA3EEF3AD |
Calls SceSblGcAuthMgrPcactForDriver_B7AE58B9.
// entropy size is 0x20 bytes // challenge size is 0x80 bytes int sceSblGcAuthMgrPcactGetChallengeForDriver(SceUID id, const char *entropy, char *challenge);
SceSblGcAuthMgrPcactForDriver_B7AE58B9
Version | NID |
---|---|
0.990 | 0xB7AE58B9 |
// challenge size is 0x80 bytes // buf_40 size is 0x40 bytes int SceSblGcAuthMgrPcactForDriver_B7AE58B9(SceUID id, uint a2, uint a3, char *challenge, void *buf_40);
get_aes_dec_key
Version | NID |
---|---|
0.990 | 0xCA97CE1C |
// act_data size is 0x1040 bytes // buf_40 size is 0x40 bytes // aes_dec_key_size is 0x20 bytes int get_aes_dec_key(const char *act_data, void *buf_40, void *aes_dec_key);
SceSblGcAuthMgrMlnpsnlForDriver
sceSblGcAuthMgrMlnpsnlAuth2ForDriver
Version | NID |
---|---|
0.940-3.60 | 0x296ABD68 |
sceSblGcAuthMgrMlnpsnlAuth1ForDriver
Version | NID |
---|---|
0.940-3.60 | 0xDABC01F5 |
SceSblGcAuthMgrPkgForDriver
sceSblGcAuthMgrPkgVryForDriver
Version | NID |
---|---|
0.990-3.60 | 0xE459A9A8 |
Calls F00D_Commands#0x11_kirk_ecc160_verify KIRK command 0x11 to verify PKG ECDSA signature.
// sha1 size is 0x14 bytes // ecc_sig size is 28 bytes (2 * 0x14 bytes) int sceSblGcAuthMgrPkgVryForDriver(const char *sha1, const char *ecc_sig);
SceSblGcAuthMgrSclkForDriver
SceSblGcAuthMgrSclkForDriver_11D5570B
Version | NID |
---|---|
3.60 | 0x11D5570B |
SceSblGcAuthMgrSclkForDriver_F723A9BA
Version | NID |
---|---|
3.60 | 0xF723A9BA |
SceSblGcAuthMgrGcAuthForDriver
cmd56_handshake
Version | NID |
---|---|
3.60 | 0x68781760 |
This is a wrapper function that starts initialization subroutine through run_exclusively().
int cmd56_handshake(int sd_ctx_index);
SceSblGcAuthMgrPsmactForDriver
get_act_data
Version | NID |
---|---|
3.60 | 0x39222A58 |
Executes KIRK command 0x1000B 19.
// data is of size 0x80 int get_act_data(void* data);
SceSblGcAuthMgrMsSaveBBForDriver
SceSblGcAuthMgrMsSaveBBForDriver_3C185A67
Version | NID |
---|---|
3.60 | 0x3C185A67 |
SceSblGcAuthMgrMsSaveBBForDriver_4A249828
Version | NID |
---|---|
3.60 | 0x4A249828 |
SceSblGcAuthMgrMsSaveBBForDriver_79A9BE44
Version | NID |
---|---|
3.60 | 0x79A9BE44 |
SceSblGcAuthMgrMsSaveBBForDriver_805C860B
Version | NID |
---|---|
3.60 | 0x805C860B |
SceSblGcAuthMgrMsSaveBBForDriver_8E6626A0
Version | NID |
---|---|
3.60 | 0x8E6626A0 |
SceSblGcAuthMgrMsSaveBBForDriver_F66D5F76
Version | NID |
---|---|
3.60 | 0xF66D5F76 |
SceSblGcAuthMgr
_sceSblGcAuthMgrPcactActivation
Version | NID |
---|---|
0.990-3.60 | 0x032E7CEA |
typedef struct ScePcactActivationData { // size is 0x1090 on FW 0.990 char unk_buf[0x50]; char act_data[0x1040]; } ScePcactActivationData; int _sceSblGcAuthMgrPcactActivation(const ScePcactActivationData *act_data, SceSize act_data_size);
_sceSblGcAuthMgrMsSaveBBCipherInit
Version | NID |
---|---|
3.60 | 0x064BA38A |
_sceSblGcAuthMgrAdhocBB160Shutdown
Version | NID |
---|---|
3.60 | 0x076ADAB3 |
_sceSblGcAuthMgrAdhocBB160UniCastEncrypt
Version | NID |
---|---|
3.60 | 0x08C4EE5F |
_sceSblGcAuthMgrAdhocBB160GetKeys
Version | NID |
---|---|
3.60 | 0x09E1E270 |
_sceSblGcAuthMgrGetMediaIdType01
Version | NID |
---|---|
1.69-3.60 | 0x0AC64154 |
_sceSblGcAuthMgrMsSaveBBCipherFinal
Version | NID |
---|---|
3.60 | 0x18EAAD73 |
_sceSblGcAuthMgrAdhocBB160BroadCastDecrypt
Version | NID |
---|---|
3.60 | 0x2193A7CB |
_sceSblGcAuthMgrPsmactVerifyR1
Version | NID |
---|---|
3.60 | 0x2B604356 |
_sceSblGcAuthMgrAdhocBB224Auth1
Version | NID |
---|---|
1.69-3.60 | 0x307FD67C |
_sceSblGcAuthMgrMsSaveBBMacInit
Version | NID |
---|---|
3.60 | 0x3A92780D |
_sceSblGcAuthMgrPsmactCreateC1
Version | NID |
---|---|
3.60 | 0x3BD8B007 |
_sceSblGcAuthMgrPkgVry
Version | NID |
---|---|
1.69-3.60 | 0x3E168BC4 |
_sceSblGcAuthMgrAdhocBB224Auth5
Version | NID |
---|---|
1.69-3.60 | 0x459F5503 |
_sceSblGcAuthMgrAdhocBB224Init
Version | NID |
---|---|
1.69-3.60 | 0x5AB126A7 |
_sceSblGcAuthMgrAdhocBB224Auth4
Version | NID |
---|---|
1.69-3.60 | 0x5CCC216C |
_sceSblGcAuthMgrAdhocBB160Auth1
Version | NID |
---|---|
3.60 | 0x5E56F845 |
_sceSblGcAuthMgrAdhocBB160BroadCastEncrypt
Version | NID |
---|---|
3.60 | 0x6125C3D9 |
_sceSblGcAuthMgrMsSaveBBMacUpdate
Version | NID |
---|---|
3.60 | 0x716C0C3B |
_sceSblGcAuthMgrAdhocBB224Auth2
Version | NID |
---|---|
1.69-3.60 | 0x788C0517 |
_sceSblGcAuthMgrAdhocBB160Auth4
Version | NID |
---|---|
3.60 | 0x7F33DE86 |
_sceSblGcAuthMgrSclkSetData2
Version | NID |
---|---|
0.990-3.60 | 0x837D0FB6 |
_sceSblGcAuthMgrSclkGetData1
Version | NID |
---|---|
0.990-3.60 | 0x8A3AF1E8 |
_sceSblGcAuthMgrAdhocBB224Shutdown
Version | NID |
---|---|
1.69-3.60 | 0x8ECEACF9 |
_sceSblGcAuthMgrPcactGetChallenge
Version | NID |
---|---|
0.990-3.60 | 0x98153286 |
typedef struct ScePcactGetChallengeOpt { // size is 0x10 on FWs 0.990-3.60 SceSize entropySize; // Maximum size is 0x20 bytes SceSize challengeSize; // Maximum size is 0x80 bytes char reserved[8]; } ScePcactGetChallengeOpt; int _sceSblGcAuthMgrPcactGetChallenge(int id, const char *entropy, char *challenge, ScePcactGetChallengeOpt *pOpt);
_sceSblGcAuthMgrAdhocBB224GetKeys
Version | NID |
---|---|
1.69-3.60 | 0xC236FB28 |
_sceSblGcAuthMgrAdhocBB160Auth3
Version | NID |
---|---|
3.60 | 0xD1777A14 |
_sceSblGcAuthMgrAdhocBB160Auth2
Version | NID |
---|---|
3.60 | 0xD2218A6E |
_sceSblGcAuthMgrAdhocBB224Auth3
Version | NID |
---|---|
1.69-3.60 | 0xD3F95259 |
_sceSblGcAuthMgrAdhocBB160UniCastDecrypt
Version | NID |
---|---|
3.60 | 0xD79A1B31 |
_sceSblGcAuthMgrAdhocBB160Auth5
Version | NID |
---|---|
3.60 | 0xD84C2E0C |
_sceSblGcAuthMgrAdhocBB160Init
Version | NID |
---|---|
3.60 | 0xE4AA1BB2 |
_sceSblGcAuthMgrMsSaveBBCipherUpdate
Version | NID |
---|---|
3.60 | 0xF6FECCE0 |
_sceSblGcAuthMgrMsSaveBBMacFinal
Version | NID |
---|---|
3.60 | 0xFDDDD1D4 |
gcauth_sm "KIRK" calls to F00D
The use of os0:sm/gcauthmgr_sm.self is to support the next generation of KIRK. It uses a similar input structure to the original KIRK on the PSP.
PSP support
4, 7, 0xC, 0xD, 0xE, 0x10, 0x11, 0x12 are the classic PSP KIRK Services supported by gcauth_sm.
New PSVita Codes
0x14-0x19, 0x1B-0x23 are the new KIRK Services supported by gcauth_sm.
0x14 is the 224bit ecdsa keypair gen. The only input is an empty buffer size (3*0x1C) it returns 3 values. Private key, Public X point, Public Y point. Each value is 0x1C bytes long.
0x16 is random 224bit generator. It will return 0x1C bytes of random data into the buffer. 0x17-0x19 are the 224bit ecdsa versions of PSP's 160bit 0x10-0x12.
PSN Activation Block
On 7/29/2017, all hacked Vitas on 3.60 spoofing the latest firmware (3.65) were blocked from console activation. This is particularly odd because the PSN passphrase did not change in 3.65. Additionally with the release of [ensō](https://enso.henkaku.xyz/) added to the confusion of what happened. Here is the result of a preliminary investigation of the situation.
Upon game activation, the Vita displays an dialog that shows the error number E-80558325
. This error number is used in SceNpKdc, which is found in vs0:external/np_kdc.suprx
. The error code itself is created when the activation response is received:
v5 = v45 | 0x80558300;
Here, v5
is the return code and v45
is the string error code from the server converted to a number. The request made to Sony's server looks like the following
Content-Type: application/x-www-form-urlencoded User-Agent: My heart leaps up when I behold A rainbow in the sky X-I-5-DRM-Version: 1.0 loginid=PSNID&epassword=ENCRYPTEDPASSWORD&platform=psp2&c1=CHALLENGESTRING
The request from a 3.65 stock console has the same headers and loginid
and epassword
(for the same account) so the only change visible to Sony is the challenge string c1
.
The response you get on 3.60 is
HTTP/1.0 200 OK Server: Apache X-I-5-DRM-Version: 1.0 X-I-5-DRM-Status: NG; reason=25 Content-Length: 0 Content-Type: application/x-i-5-drm X-N: S Date: Sat, 29 Jul 2017 23:01:31 GMT Connection: keep-alive
Challenge
The challenge string is constructed in SceNpKdc with a call to SceLibKernel_9557D15C
. Farther investigation shows that SceLibKernel_9557D15C
likely has the following call type:
int sceKernelPcactGetChallenge(int id, const char entropy[32], char challenge[128]);
It is called with id = 0
and entropy
set to uninitialized stack space. Tracing this call, you eventually arrive at a kernel function in SceSblGcAuthMgrPcactForDriver
with the NID 0xB7AE58B9
. This call looks like the following
typedef struct { uint8_t length; // must be 16 uint8_t unk[15]; // must all be 0 uint8_t entropy[32]; // from user } challengeInput_t; int createPcactChallenge(int id, const challengeInput_t *in, uint64_t *rtc_seconds, char challenge[128], char output[16]);
It appears that data from aimgr_sm.self
(F00D Commands) along with in
, rtc_seconds
(the RTC in seconds), DMAC engine, and maybe other data are entangled together into a 112 byte sized block. Then a 20 byte SHA1-HMAC is computed over the buffer with some key. It is likely that the data itself is unimportant and just has to be random and console unique.
This is the challenge string generation code, reverse engineered from PSP openpsid.prx (same code as in vita):
#define KIRK_CMD_ENCRYPT_IV_0 4 #define KIRK_CMD_DECRYPT_IV_0 7 #define KIRK_CMD_SHA1_HASH 11 #define KIRK_CMD_PRNG 14 static int DecryptIV0(u32 *buf, u32 size, u32 code) { buf[0] = 5; buf[1] = 0; buf[2] = 0; buf[3] = code; buf[4] = size; return sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size+0x14, KIRK_CMD_DECRYPT_IV_0); } static int EncryptIV0(u32 *buf, u32 size, u32 code) { buf[0] = 4; buf[1] = 0; buf[2] = 0; buf[3] = code; buf[4] = size; return sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size+0x14, KIRK_CMD_ENCRYPT_IV_0); } static int generate_challenge(u8 mode, u8 *psid, u8 *entropy, u64 *rtc_tick, u8 *challenge, u8 *prng) { static u8 data_38BC[0x10] = { 0x38, 0x0A, 0x18, 0x0E, 0x36, 0x58, 0xBC, 0xC1, 0x70, 0x64, 0x69, 0xE3, 0x29, 0x60, 0x81, 0xF9 }; static u8 data_38DC[0x10] = { 0xCA, 0x0E, 0x20, 0x6E, 0xCE, 0xE6, 0xFB, 0x66, 0x68, 0x28, 0x65, 0x42, 0xEF, 0x4F, 0xF8, 0x8F }; static u8 work[0xB8]; static u8 challenge_work[0x70]; int res; int i; memset(work, 0, 0xB8); memset(challenge_work, 0, 0x70); memset(challenge, 0, 0x80); memset(prng, 0, 0x40); // get random data res = sceUtilsBufferCopyWithRange(work, 0x14, 0, 0, KIRK_CMD_PRNG); if (res < 0) return -2; memcpy(prng, work, 0x10); // encrypt prng memcpy(work+0x14, prng, 0x10); res = DecryptIV0(work, 0x10, 0x68); if (res < 0) return -3; memcpy(prng+0x10, work, 0x10); prng[0x20] = mode; memcpy(challenge_work, work, 0x10); // random data memcpy(challenge_work+0x10, data_38DC, 0x10); // constant data // encrypt psid memcpy(work+0x14, psid, 0x10); res = DecryptIV0(work, 0x10, 0x68); if (res < 0) return -3; memcpy(challenge_work+0x20, work, 0x10); // encrypted psid memcpy(challenge_work+0x30, rtc_tick, 0x8); // rtc tick memcpy(challenge_work+0x38, entropy+0x10, 0x20); // entropy, 32 bytes of epassword // fuseid u32 fuseid0 = *(u32 *)0xBC100090; u32 fuseid1 = *(u32 *)0xBC100094; challenge_work[0x58] = fuseid1 >> 24; challenge_work[0x59] = fuseid1 >> 16; challenge_work[0x5A] = fuseid1 >> 8; challenge_work[0x5B] = fuseid1; challenge_work[0x5C] = fuseid0 >> 24; challenge_work[0x5D] = fuseid0 >> 16; challenge_work[0x5E] = fuseid0 >> 8; challenge_work[0x5F] = fuseid0; memcpy(work+0x14, challenge_work, 0x60); // xor with data_38BC keys for (i = 0; i < 0x60; i++) { work[0x14+i] ^= data_38BC[i % 0x10]; } // encrypt data res = EncryptIV0(work, 0x60, 0x13); if (res < 0) return -4; // xor encrypted data with data_38BC keys for (i = 0; i < 0x60; i++) { work[0x14+i] ^= data_38BC[i % 0x10]; } // build challenge string memset(challenge_work, 0, 0x10); challenge_work[0x00] = 0x11; challenge_work[0x01] = 0x01; challenge_work[0x02] = mode; memcpy(challenge_work+0x10, work+0x14, 0x60); // get sha1 hash digest *(u32 *)work = 0x80; memcpy(work+0x04, data_38BC, 0x10); memcpy(work+0x14, challenge_work, 0x70); res = sceUtilsBufferCopyWithRange(work, 0x84, work, 0x84, KIRK_CMD_SHA1_HASH); if (res < 0) return -5; // encrypt hash digest memcpy(work+0x14, work, 0x10); res = EncryptIV0(work, 0x10, 0x13); if (res < 0) return -4; // copy challenge string memcpy(challenge, challenge_work, 0x70); memcpy(challenge+0x70, work+0x14, 0x10); return 0; }
How Sony Blocked Activation
There are at least two possible ways. First is that on 3.65, the random-looking data block has some specific structure that Sony looks for (or some console unique data in this block gives away the fact that the console is on 3.60). Second is that they changed the SHA1-HMAC key. If it is the latter case, then the next step is to find how this key is constructed. It is likely that the key is constructed in F00D and therefore spoofing it would require a F00D hack.
How Hackers Bypassed The Block
See ReStore / ReNpDrm vulnerability by CelesteBlue.
How Sony Unblocked Activation
Since May 2018, the challenge string in requests sent from PSVita to PSN for Content and PSN Account activations is not checked anymore. Strange...
I can think about 4 reasons:
1) Sony wanted to fight ReStore by killing its purpose. In that case, they would have better patched the vulnerability...
2) Sony has done that by mistake. Impossible.
3) Sony is working on a more secure PSN. We have an exemple: when Sony removed ConsoleId checks on its servers for 3 months, then restored the check with even more securities. In the PSVita case, they would have been quicker at fixing challenge if that was for security.
4) Sony is working on a big change of PSN. This is very plausible since we discovered they are adapting old PSN to work with a new "Account Id" because now people can change PSN ID.