SceSblGcAuthMgr: Difference between revisions

From Vita Development Wiki
Jump to navigation Jump to search
 
(57 intermediate revisions by 3 users not shown)
Line 1: Line 1:
SBL Game Card Auth Manager
== Module ==
== Module ==


=== Known NIDs ===
{| class="wikitable"
{| class="wikitable"
|-
|-
! Version !! Name !! World !! Privilege !! NID
! Version !! World !! Privilege
|-
|-
| 1.69 || SceSblGcAuthMgr || Non-secure || Kernel || 0x4B777EBC
| 1.69-3.60 || Non-secure || Kernel
|-
| 3.60 || SceSblGcAuthMgr || Non-secure || Kernel || 0xDB1A9016
|}
|}


Line 19: Line 18:
! Version !! Name !! World !! Visibility !! NID
! Version !! Name !! World !! Visibility !! NID
|-
|-
| 1.69 || [[SceSblGcAuthMgr#SceSblGcAuthMgrDrmBBForDriver|SceSblGcAuthMgrDrmBBForDriver]] || Non-secure || Kernel || 0x1926B182
| 1.69-3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgrDrmBBForDriver|SceSblGcAuthMgrDrmBBForDriver]] || Non-secure || Kernel || 0x1926B182
|-
| 3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgrDrmBBForDriver|SceSblGcAuthMgrDrmBBForDriver]] || Non-secure || Kernel || 0x1926B182
|-
|-
| 1.69 || [[SceSblGcAuthMgr#SceSblGcAuthMgrPcactForDriver|SceSblGcAuthMgrPcactForDriver]] || Non-secure || Kernel || 0x0B8600A5
| 1.69 || [[SceSblGcAuthMgr#SceSblGcAuthMgrPcactForDriver|SceSblGcAuthMgrPcactForDriver]] || Non-secure || Kernel || 0x0B8600A5
|-
|-
| 3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgrPcactForDriver|SceSblGcAuthMgrPcactForDriver]] || Non-secure || Kernel || NOT PRESENT
| 3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgrPcactForDriver|SceSblGcAuthMgrPcactForDriver]] || Non-secure || Kernel || not present
|-
| 1.69 || [[SceSblGcAuthMgr#SceSblGcAuthMgrMlnpsnlForDriver|SceSblGcAuthMgrMlnpsnlForDriver]] || Non-secure || Kernel || 0x29ED0109
|-
|-
| 3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgrMlnpsnlForDriver|SceSblGcAuthMgrMlnpsnlForDriver]] || Non-secure || Kernel || 0x29ED0109
| 1.69-3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgrMlnpsnlForDriver|SceSblGcAuthMgrMlnpsnlForDriver]] || Non-secure || Kernel || 0x29ED0109
|-
|-
| 1.69 || [[SceSblGcAuthMgr#SceSblGcAuthMgrAdhocBBForDriver|SceSblGcAuthMgrAdhocBBForDriver]] || Non-secure || Kernel || 0x2EFA9203
| 1.69 || [[SceSblGcAuthMgr#SceSblGcAuthMgrAdhocBBForDriver|SceSblGcAuthMgrAdhocBBForDriver]] || Non-secure || Kernel || 0x2EFA9203
|-
|-
| 3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgrAdhocBBForDriver|SceSblGcAuthMgrAdhocBBForDriver]] || Non-secure || Kernel || NOT PRESENT
| 3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgrAdhocBBForDriver|SceSblGcAuthMgrAdhocBBForDriver]] || Non-secure || Kernel || not present
|-
| 1.69 || [[SceSblGcAuthMgr#SceSblGcAuthMgrPkgForDriver|SceSblGcAuthMgrPkgForDriver]] || Non-secure || Kernel || 0x082FBA7D
|-
|-
| 3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgrPkgForDriver|SceSblGcAuthMgrPkgForDriver]] || Non-secure || Kernel || 0x082FBA7D
| 1.69-3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgrPkgForDriver|SceSblGcAuthMgrPkgForDriver]] || Non-secure || Kernel || 0x082FBA7D
|-
|-
| 1.69 || [[SceSblGcAuthMgr#SceSblGcAuthMgrSclkForDriver|SceSblGcAuthMgrSclkForDriver]] || Non-secure || Kernel || 0xF24F760D
| 1.69-3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgrSclkForDriver|SceSblGcAuthMgrSclkForDriver]] || Non-secure || Kernel || 0xF24F760D
|-
|-
| 3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgrSclkForDriver|SceSblGcAuthMgrSclkForDriver]] || Non-secure || Kernel || 0xF24F760D
| 1.69-3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgrGcAuthForDriver|SceSblGcAuthMgrGcAuthForDriver]] || Non-secure || Kernel || 0xC6627F5E
|-
|-
| 1.69 || [[SceSblGcAuthMgr#SceSblGcAuthMgrGcAuthForDriver|SceSblGcAuthMgrGcAuthForDriver]] || Non-secure || Kernel || 0xC6627F5E
| 1.69-3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgr|SceSblGcAuthMgr]] || Non-secure || User || 0x7B13BCF7
|-
| 3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgrGcAuthForDriver|SceSblGcAuthMgrGcAuthForDriver]] || Non-secure || Kernel || 0xC6627F5E
|-
| 1.69 || [[SceSblGcAuthMgr#SceSblGcAuthMgr|SceSblGcAuthMgr]] || Non-secure || User || 0x7B13BCF7
|-
| 3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgr|SceSblGcAuthMgr]] || Non-secure || User || 0x7B13BCF7
|-
|-
| 3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgrPsmactForDriver|SceSblGcAuthMgrPsmactForDriver]] || Non-secure || Kernel || 0x1C53F37D
| 3.60 || [[SceSblGcAuthMgr#SceSblGcAuthMgrPsmactForDriver|SceSblGcAuthMgrPsmactForDriver]] || Non-secure || Kernel || 0x1C53F37D
Line 70: Line 57:
| 0x4DF4 || 0x04 || packet6 gc parameter
| 0x4DF4 || 0x04 || packet6 gc parameter
|-
|-
| 0x4DF8 || 0x200 || temp buffer for initializing cm56 req packets
| 0x4DF8 || 0x200 || temp buffer for initializing cmd56 req packets
|-
|-
| 0x4FF8 || 0x20 || temp buffer for storing parts of cmd56 packets
| 0x4FF8 || 0x20 || temp buffer for storing parts of cmd56 packets
|-
|-
| 0x5018 || 0x34 || one of kirk responses
| 0x5018 || 0x34 || one of Kirk responses
|-
|-
| 0x504C || 0x200 || cmd56 response buffer 1
| 0x504C || 0x200 || cmd56 response buffer 1
Line 80: Line 67:
| 0x524C || 0x200 || cmd56 response buffer 2
| 0x524C || 0x200 || cmd56 response buffer 2
|-
|-
| 0x544C || 0x20 || one of kirk responses
| 0x544C || 0x20 || one of Kirk responses
|-
|-
| 0x546C || 0x898 || unknown
| 0x546C || 0x898 || unknown
Line 105: Line 92:
|}
|}


Almost certainly a 224bit version of 0x11
224bit version of PSP Kirk 0x11 service


=== command 0x1000B 0x21 ===
=== command 0x1000B 0x21 ===
Line 138: Line 125:
! Version !! NID
! Version !! NID
|-
|-
| 3.60 || 0x6EF3C9DB
| 0.990-3.60 || 0x6EF3C9DB
|}
|}


Line 214: Line 201:


<source lang="C">
<source lang="C">
typedef struct ctx_48D7784E //size is 0x28
typedef struct ctx_48D7784E { //size is 0x28
{
   uint32_t unk_0;
   uint32_t unk_0;
   char unk_4[0x10];
   char unk_4[0x10];
Line 233: Line 219:
|}
|}
<source lang="C">
<source lang="C">
typedef struct ctx_6E6D2B89 //size is 0x18
typedef struct ctx_6E6D2B89 { //size is 0x18
{
   uint32_t unk_0;
   uint32_t unk_0;
   uint32_t unk_4;
   uint32_t unk_4;
   char unk_8[0x10];
   char unk_8[0x10];
}ctx_6E6D2B89;
} ctx_6E6D2B89;


int clear_context(ctx_6E6D2B89 *ctx);
int clear_context(ctx_6E6D2B89 *ctx);
Line 251: Line 236:
|}
|}


Includes both aes and psp kirk 0x1000B 4 and 7
Includes both AES and PSP Kirk 0x1000B 4 and 7.


<source lang="C">int enc_dec(void* data, void* dec_rif_key, int unk2, void* unk3);</source>
<source lang="C">int enc_dec(void* data, void* dec_rif_key, int unk2, void* unk3);</source>
Line 260: Line 245:
! Version !! NID
! Version !! NID
|-
|-
| 3.60 || 0x535B87BC
| 0.990-3.60 || 0x535B87BC
|}
|}


Line 270: Line 255:
! Version !! NID
! Version !! NID
|-
|-
| 3.60 || 0xBB70DDC0
| 0.990-3.60 || 0xBB70DDC0
|}
|}


This function copies first 0x20 bytes of the buffer of size 0x34 to destination.
This function copies first 0x20 bytes of the buffer of size 0x34 to destination.


Buffer is obtained with [[F00D_Commands#0x20|KIRK command 0x20]].
Buffer is obtained with [[Secure_Modules_Functions#0x20|KIRK command 0x20]].


<source lang="C">int get_5018_data(char* dest);</source>
<source lang="C">int get_5018_data(char* dest);</source>


=== memcmp_5018_fast ===
=== memcmp_safe_5018 ===
{| class="wikitable"
{| class="wikitable"
|-
|-
! Version !! NID
! Version !! NID
|-
|-
| 3.60 || 0x22FD5D23
| 0.990-3.60 || 0x22FD5D23
|}
|}


This function verifies that last 0x14 bytes of last response of size 0x34 from the game card (cmd56) are valid
Temp name was memcmp_5018_fast.


CMD56 response is obtained with Buffer is obtained with [[F00D_Commands#0x20|KIRK command 0x20]]
This function verifies that last 0x14 bytes of last response of size 0x34 from the game card (cmd56) are valid.


For example it is called from <code>sceAppMgrGameDataMount</code>
CMD56 response Buffer is obtained with [[Secure_Modules_Functions#0x20|KIRK command 0x20]]


<source lang="c">int memcmp_5018_fast(char* in_data);</source>
For example it is called from [[SceAppMgr#sceAppMgrGameDataMount]].


This is a timing safe memcmp. [[User:Xyz|Xyz]] ([[User talk:Xyz|talk]]) 10:02, 1 May 2017 (UTC)
This is a timing safe memcmp. [[User:Xyz|Xyz]] ([[User talk:Xyz|talk]]) 10:02, 1 May 2017 (UTC)
<source lang="c">int memcmp_safe_5018(char* in_data);</source>


=== clear_sensitive_data ===
=== clear_sensitive_data ===
Line 302: Line 289:
! Version !! NID
! Version !! NID
|-
|-
| 3.60 || 0x812B2B5C
| 0.990-3.60 || 0x812B2B5C
|}
|}


Clears some sensitive data.  
Clears some sensitive data.  


Called after <code>verify_checksum</code>.
Called after <code>memcmp_safe_5018</code>.


<source lang="c">int clear_sensitive_data(int unk, int* value);</source>
<source lang="c">int clear_sensitive_data(int unk, int* value);</source>


=== clear_sensitive_data ===
=== clear_sensitive_data_2 ===
{| class="wikitable"
{| class="wikitable"
|-
|-
! Version !! NID
! Version !! NID
|-
|-
| 3.60 || 0xBB451E83
| 0.990-3.60 || 0xBB451E83
|}
|}


Line 327: Line 314:
Called after <code>initialize_sd_device</code>.
Called after <code>initialize_sd_device</code>.


<source lang="c">int clear_sensitive_data();</source>
<source lang="c">int clear_sensitive_data_2();</source>


== SceSblGcAuthMgrAdhocBBForDriver ==
== SceSblGcAuthMgrAdhocBBForDriver ==


Present on 1.69. Not present on 3.60+.
Present on FW 1.69. Not present on FWs >= 3.60.
 
=== sceSblGcAuthMgrAdhocBB224InitForDriver ===
{| class="wikitable"
|-
! Version !! NID
|-
| 0.940 || 0xAD28D0FC
|}
 
=== sceSblGcAuthMgrAdhocBB224ShutdownForDriver ===
{| class="wikitable"
|-
! Version !! NID
|-
| 0.940 || 0xF373E805
|}
 
=== sceSblGcAuthMgrAdhocBB224GetKeysForDriver ===
{| class="wikitable"
|-
! Version !! NID
|-
| 0.940 || 0x8558BE2C
|}
 
=== sceSblGcAuthMgrAdhocBB224Auth1ForDriver ===
{| class="wikitable"
|-
! Version !! NID
|-
| 0.940 || 0x0FD3C103
|}
 
=== sceSblGcAuthMgrAdhocBB224Auth2ForDriver ===
{| class="wikitable"
|-
! Version !! NID
|-
| 0.940 || 0xCBC471F2
|}
 
=== sceSblGcAuthMgrAdhocBB224Auth3ForDriver ===
{| class="wikitable"
|-
! Version !! NID
|-
| 0.940 || 0x772914E5
|}
 
=== sceSblGcAuthMgrAdhocBB224Auth4ForDriver ===
{| class="wikitable"
|-
! Version !! NID
|-
| 0.940 || 0x7EDBBBF8
|}
 
=== sceSblGcAuthMgrAdhocBB224Auth5ForDriver ===
{| class="wikitable"
|-
! Version !! NID
|-
| 0.940 || 0x79DD1A5E
|}


== SceSblGcAuthMgrPcactForDriver ==
== SceSblGcAuthMgrPcactForDriver ==


Present on 1.69. Not present on 3.60+.
This library is present on System Software versions 0.990.000-1.692.000. Not present since System Software version 1.80.
 
=== sceSblGcAuthMgrPcactActivationForDriver ===
{| class="wikitable"
|-
! Version !! NID
|-
| 0.990.000-1.692.000 || 0x46B7AA5A
|}
 
Calls get_aes_dec_key then [[SceNpDrm]] set_act_data.
 
<source lang="C">
typedef struct ScePcactUnkBuf { // size is 0x50 on FW 0.990
  short unk_0; // must be 0x211
  char mode;
  char reserved[0xD]; // must be zeroed
  char unk_10[0x40]; // might be keys generated from ConsoleId
} ScePcactUnkBuf;
 
typedef struct ScePcactActivationData { // size is 0x1090 on FW 0.990
  ScePcactUnkBuf unk_buf;
  char act_dat[0x1040];
} ScePcactActivationData;
 
int sceSblGcAuthMgrPcactActivationForDriver(const ScePcactActivationData *act_data, SceSize act_data_size);</source>
 
=== sceSblGcAuthMgrPcactGetChallengeForDriver ===
{| class="wikitable"
|-
! Version !! NID
|-
| 0.990.000-1.692.000 || 0xA3EEF3AD
|}
 
Calls [[#SceSblGcAuthMgrPcactForDriver_B7AE58B9]].
 
<source lang="C">
// entropy (epassword) size is 0x20 bytes
// challenge size is 0x80 bytes
int sceSblGcAuthMgrPcactGetChallengeForDriver(SceUID id, const char *entropy, char *challenge);
</source>
 
=== SceSblGcAuthMgrPcactForDriver_B7AE58B9 ===
{| class="wikitable"
|-
! Version !! NID
|-
| 0.990.000-1.692.000 || 0xB7AE58B9
|}
 
<source lang="C">
typedef struct ScePcactCreateChallengeOpt {
    char data_offset;      // must be 0x10
    char reserved[15];    // must be zeroed
    char epassword[32];
} ScePcactCreateChallengeOpt;
 
// challenge size is 0x80 bytes
// prng size is 0x40 bytes
int SceSblGcAuthMgrPcactForDriver_B7AE58B9(SceUInt32 mode, ScePcactCreateChallengeOpt *pOpt, SceUInt64 *rtc_tick, void *challenge, void *prng);
</source>
 
=== get_aes_dec_key ===
{| class="wikitable"
|-
! Version !! NID
|-
| 0.990.000-1.692.000 || 0xCA97CE1C
|}
 
aes_dec_key is derived from act_data. prng seems to be a temporary work buffer.
 
<source lang="C">
// prng size is 0x40 bytes
// aes_dec_key size is 0x10 bytes
int get_aes_dec_key(const ScePcactActivationData *act_data, void *prng, void *aes_dec_key);
</source>


== SceSblGcAuthMgrMlnpsnlForDriver ==
== SceSblGcAuthMgrMlnpsnlForDriver ==


=== SceSblGcAuthMgrMlnpsnlForDriver_296ABD68 ===
=== sceSblGcAuthMgrMlnpsnlAuth1ForDriver ===
{| class="wikitable"
{| class="wikitable"
|-
|-
! Version !! NID
! Version !! NID
|-
|-
| 3.60 || 0x296ABD68
| 0.940-3.60 || 0xDABC01F5
|}
|}


=== SceSblGcAuthMgrMlnpsnlForDriver_DABC01F5 ===
=== sceSblGcAuthMgrMlnpsnlAuth2ForDriver ===
{| class="wikitable"
{| class="wikitable"
|-
|-
! Version !! NID
! Version !! NID
|-
|-
| 3.60 || 0xDABC01F5
| 0.940-3.60 || 0x296ABD68
|}
|}


== SceSblGcAuthMgrPkgForDriver ==
== SceSblGcAuthMgrPkgForDriver ==


=== SceSblGcAuthMgrPkgForDriver_E459A9A8 ===
=== sceSblGcAuthMgrPkgVryForDriver ===
{| class="wikitable"
{| class="wikitable"
|-
|-
! Version !! NID
! Version !! NID
|-
|-
| 3.60 || 0xE459A9A8
| 0.990-3.60 || 0xE459A9A8
|}
|}
Calls [[Secure_Modules_Functions#0x11_kirk_ecc160_verify KIRK command 0x11]] to verify PKG ECDSA signature.
<source lang="C">
// pHash: sha1 hash of data (0x14 bytes)
// pSig: ECDSA signature (2 * 0x14 bytes)
int sceSblGcAuthMgrPkgVryForDriver(const char *pHash, const char *pSig);
</source>


== SceSblGcAuthMgrSclkForDriver ==
== SceSblGcAuthMgrSclkForDriver ==


=== SceSblGcAuthMgrSclkForDriver_11D5570B ===
Related to Secure clock.
 
=== sceSblGcAuthMgrSclkGetData1ForDriver ===
{| class="wikitable"
{| class="wikitable"
|-
|-
! Version !! NID
! Version !! NID
|-
|-
| 3.60 || 0x11D5570B
| 0.990-3.60 || 0x11D5570B
|}
|}


=== SceSblGcAuthMgrSclkForDriver_F723A9BA ===
AES256ECB encrypts a buffer made from a "genuine random number" followed by zeroes.
 
<source lang="C">
typedef struct SceSblGcAuthMgrSclkData1 { // size is 0x30
  int unk_0; // ex: 1
  int unk_4; // ex: 1
  int unk_8; // ex: 0
  int unk_C; // ex: 0
  char enc_data_0[0x10]; // seed = zeroes
  char enc_data_1[0x10]; // seed = hardcoded
} SceSblGcAuthMgrSclkData1;
 
int sceSblGcAuthMgrSclkGetData1ForDriver(SceSblGcAuthMgrSclkData1 *pData);
</source>
 
=== sceSblGcAuthMgrSclkSetData2ForDriver ===
{| class="wikitable"
{| class="wikitable"
|-
|-
! Version !! NID
! Version !! NID
|-
|-
| 3.60 || 0xF723A9BA
| 0.990-3.60 || 0xF723A9BA
|}
|}
Checks header, sha256, AES256ECB decrypts then sets some secure RTC.
<source lang="C">
typedef struct SceSblGcAuthMgrSclkData2 { // size is at least 0x30
  int unk_0; // ex: 1
  int unk_4; // ex: 1
  int unk_8; // ex: 0
  int unk_C; // ex: 0
  char enc_data_0[0x10];
  char enc_data_1[0x10];
  // more, maybe sha256
} SceSblGcAuthMgrSclkData2;
int sceSblGcAuthMgrSclkSetData2ForDriver(SceSblGcAuthMgrSclkData2 *pData);
</source>


== SceSblGcAuthMgrGcAuthForDriver ==
== SceSblGcAuthMgrGcAuthForDriver ==
Line 393: Line 562:
|}
|}


This is a wrapper function that starts initialization subroutine through [[SceKernelThreadMgr#Run_Exclusively|run_exclusively()]].
This is a wrapper function that starts initialization subroutine through [[SceKernelThreadMgr#_sceKernelExtendKernelStackWideForDriver]].
 
<source lang="c">int cmd56_handshake(int sd_ctx_index);</source>
 


<source lang="c">int cmd56_handshake(SceUInt32 keyid);</source>


== SceSblGcAuthMgrPsmactForDriver ==
== SceSblGcAuthMgrPsmactForDriver ==
Line 406: Line 573:
! Version !! NID
! Version !! NID
|-
|-
| 3.60 || 0x39222A58
| 0.931.010-1.692.000 || not present
|-
| 1.800.071-3.740.011 || 0x39222A58
|}
|}


Line 418: Line 587:
== SceSblGcAuthMgrMsSaveBBForDriver ==
== SceSblGcAuthMgrMsSaveBBForDriver ==


=== SceSblGcAuthMgrMsSaveBBForDriver_3C185A67 ===
=== sceSblGcAuthMgrMsSaveBBCipherInitForDriver ===
{| class="wikitable"
{| class="wikitable"
|-
|-
Line 426: Line 595:
|}
|}


=== SceSblGcAuthMgrMsSaveBBForDriver_4A249828 ===
AES encrypts with null IV using a Kirk command.
 
=== sceSblGcAuthMgrMsSaveBBMacInitForDriver ===
{| class="wikitable"
{| class="wikitable"
|-
|-
Line 434: Line 605:
|}
|}


=== SceSblGcAuthMgrMsSaveBBForDriver_79A9BE44 ===
<source lang="C">int sceSblGcAuthMgrMsSaveBBMacInitForDriver(void *pDst, SceUInt32 initValue);</source>
 
=== sceSblGcAuthMgrMsSaveBBMacUpdateForDriver ===
{| class="wikitable"
{| class="wikitable"
|-
|-
Line 442: Line 615:
|}
|}


=== SceSblGcAuthMgrMsSaveBBForDriver_805C860B ===
AES encrypts a 0x800 buffer.
 
=== sceSblGcAuthMgrMsSaveBBCipherFinalForDriver ===
{| class="wikitable"
{| class="wikitable"
|-
|-
Line 450: Line 625:
|}
|}


=== SceSblGcAuthMgrMsSaveBBForDriver_8E6626A0 ===
=== sceSblGcAuthMgrMsSaveBBMacFinalForDriver ===
{| class="wikitable"
{| class="wikitable"
|-
|-
Line 458: Line 633:
|}
|}


=== SceSblGcAuthMgrMsSaveBBForDriver_F66D5F76 ===
=== sceSblGcAuthMgrMsSaveBBCipherUpdateForDriver ===
{| class="wikitable"
{| class="wikitable"
|-
|-
Line 465: Line 640:
| 3.60 || 0xF66D5F76
| 3.60 || 0xF66D5F76
|}
|}
AES decrypts a 0x800 buffer then AES decrypts with null IV using a Kirk command.


== SceSblGcAuthMgr ==
== SceSblGcAuthMgr ==
Line 473: Line 650:
! Version !! NID
! Version !! NID
|-
|-
| 1.69 || 0x032E7CEA
| 0.990-3.60 || 0x032E7CEA
|-
| 3.60 || 0x032E7CEA
|}
|}
<source lang="C">int _sceSblGcAuthMgrPcactActivation(const ScePcactActivationData *act_data, SceSize act_data_size);</source>


=== _sceSblGcAuthMgrMsSaveBBCipherInit ===
=== _sceSblGcAuthMgrMsSaveBBCipherInit ===
Line 515: Line 692:
! Version !! NID
! Version !! NID
|-
|-
| 1.69 || 0x0AC64154
| 1.03 || not present
|-
|-
| 3.60 || 0x0AC64154
| 1.69-3.60 || 0x0AC64154
|}
|}
Returns MediaIdType01 by using Kirk command 0x23 on a global buffer.
<source lang="C">
typedef struct SceMediaIdType01 {
  char enc_data[0x10]; // encrypted data
  char enc_data_cmac[0x10]; // CMAC of encrypted data
} SceMediaIdType01;
int _sceSblGcAuthMgrGetMediaIdType01(SceMediaIdType01 **pMediaId);
</source>


=== _sceSblGcAuthMgrMsSaveBBCipherFinal ===
=== _sceSblGcAuthMgrMsSaveBBCipherFinal ===
Line 549: Line 737:
! Version !! NID
! Version !! NID
|-
|-
| 1.69 || 0x307FD67C
| 1.69-3.60 || 0x307FD67C
|-
| 3.60 || 0x307FD67C
|}
|}


Line 575: Line 761:
! Version !! NID
! Version !! NID
|-
|-
| 1.69 || 0x3E168BC4
| 1.69-3.60 || 0x3E168BC4
|-
| 3.60 || 0x3E168BC4
|}
|}
<source lang="C">
typedef struct SceSblGcAuthMgrPkgVryInfo { // size is 0x10
  SceSize hashSize; // ex: 0x14
  SceSize sigSize; // ex: 0x28
  SceUInt64 reserved;
} SceSblGcAuthMgrPkgVryInfo;
// pHash: sha1 hash of data (0x14 bytes)
// pSig: ECDSA signature (2 * 0x14 bytes)
int _sceSblGcAuthMgrPkgVry(const char *pHash, const char *pSig, SceSblGcAuthMgrPkgVryInfo *pInfo);
</source>


=== _sceSblGcAuthMgrAdhocBB224Auth5 ===
=== _sceSblGcAuthMgrAdhocBB224Auth5 ===
Line 585: Line 781:
! Version !! NID
! Version !! NID
|-
|-
| 1.69 || 0x459F5503
| 1.69-3.60 || 0x459F5503
|-
| 3.60 || 0x459F5503
|}
|}


Line 595: Line 789:
! Version !! NID
! Version !! NID
|-
|-
| 1.69 || 0x5AB126A7
| 1.69-3.60 || 0x5AB126A7
|-
| 3.60 || 0x5AB126A7
|}
|}


Line 605: Line 797:
! Version !! NID
! Version !! NID
|-
|-
| 1.69 || 0x5CCC216C
| 1.69-3.60 || 0x5CCC216C
|-
| 3.60 || 0x5CCC216C
|}
|}


Line 639: Line 829:
! Version !! NID
! Version !! NID
|-
|-
| 1.69 || 0x788C0517
| 1.69-3.60 || 0x788C0517
|-
| 3.60 || 0x788C0517
|}
|}


Line 657: Line 845:
! Version !! NID
! Version !! NID
|-
|-
| 1.69 || 0x837D0FB6
| 0.990-3.60 || 0x837D0FB6
|-
| 3.60 || 0x837D0FB6
|}
|}


Line 667: Line 853:
! Version !! NID
! Version !! NID
|-
|-
| 1.69 || 0x8A3AF1E8
| 0.990-3.60 || 0x8A3AF1E8
|-
| 3.60 || 0x8A3AF1E8
|}
|}


Line 677: Line 861:
! Version !! NID
! Version !! NID
|-
|-
| 1.69 || 0x8ECEACF9
| 1.69-3.60 || 0x8ECEACF9
|-
| 3.60 || 0x8ECEACF9
|}
|}


Line 687: Line 869:
! Version !! NID
! Version !! NID
|-
|-
| 1.69 || 0x98153286
| 0.990-3.740.011 || 0x98153286
|-
| 3.60 || 0x98153286
|}
|}
<source lang="C">
typedef struct ScePcactGetChallengeOpt { // size is 0x10 on FWs 0.990-3.740.011
  SceSize epasswordSize; // Maximum size is 0x20 bytes
  SceSize challengeSize; // Maximum size is 0x80 bytes
  char reserved[8];
} ScePcactGetChallengeOpt;
int _sceSblGcAuthMgrPcactGetChallenge(SceUInt32 id, const char *epassword, char *challenge, ScePcactGetChallengeOpt *pOpt);
</source>


=== _sceSblGcAuthMgrAdhocBB224GetKeys ===
=== _sceSblGcAuthMgrAdhocBB224GetKeys ===
Line 697: Line 887:
! Version !! NID
! Version !! NID
|-
|-
| 1.69 || 0xC236FB28
| 1.69-3.60 || 0xC236FB28
|-
| 3.60 || 0xC236FB28
|}
|}


Line 723: Line 911:
! Version !! NID
! Version !! NID
|-
|-
| 1.69 || 0xD3F95259
| 1.69-3.60 || 0xD3F95259
|-
| 3.60 || 0xD3F95259
|}
|}


Line 768: Line 954:
|}
|}


== gcauth_sm "KIRK" calls to F00D ==
== gcauthmgr_sm calls to Kirk commands in cmep ==


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.
The use of os0:sm/gcauthmgr_sm.self is to support the new generation of Kirk. It uses a similar input structure to the original Kirk on the PSP.


=== PSP support ===
=== PSP Kirk support ===


4, 7, 0xC, 0xD, 0xE, 0x10, 0x11, 0x12 are the classic PSP KIRK Services supported by gcauth_sm.
4, 7, 0xC, 0xD, 0xE, 0x10, 0x11, 0x12 are the classic PSP Kirk services supported by gcauthmgr_sm. However, keys and seeds are sometimes different and look similar to PS3 crypto.


=== New PSVita Codes ===
=== New PS Vita Kirk services ===
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.
0x14-0x19, 0x1B-0x23 are the new Kirk services supported by gcauthmgr_sm. Most are just 224bit versions of original Kirk commands.


0x16 is random 224bit generator. It will return 0x1C bytes of random data into the buffer.
* 0x14 is the 224bit version of ECDSA key pair gen (Kirk command 0xC). 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.
0x17-0x19 are the 224bit ecdsa versions of PSP's 160bit 0x10-0x12.
* 0x16 is the 224bit version of pseudo random number generator (Kirk command 0xE). It will return 0x1C bytes of random data into the buffer.
* 0x17-0x19 are the 224bit ECDSA versions of PSP's 160bit Kirk commands 0x10-0x12.
* 0x1B-0x23 have no equivalent on PSP Kirk but are maybe also present on PS3


== PSN Activation Block ==
== PSN Activation Block ==
Line 823: Line 1,010:
=== Challenge ===
=== Challenge ===


The challenge string is constructed in [[SceNpKdc]] with a call to <code>SceLibKernel_9557D15C</code>. Farther investigation shows that <code>SceLibKernel_9557D15C</code> likely has the following call type:
The challenge string is constructed in [[SceNpKdc]] with a call to [[SceLibKernel#sceSblGcAuthMgrPcactGetChallenge]]. It is called with <code>id = 0</code> and <code>epassword</code> set to uninitialized stack space. Tracing this call, you eventually arrive at [[SceSblGcAuthMgr#SceSblGcAuthMgrPcactForDriver_B7AE58B9]]. It appears that data from <code>aimgr_sm.self</code> (see [[Secure Modules Functions]]) along with <code>pOpt</code>, <code>rtc_tick</code> (the RTC in seconds), DMAC engine, and maybe other data are entangled together into a 0x70-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.


<source lang="c">
This is the challenge string generation code, reverse engineered from PSP openpsid.prx (almost same code as in PS Vita):
int sceKernelPcactGetChallenge(int id, const char entropy[32], char challenge[128]);
<source lang="C">
</source>
 
It is called with <code>id = 0</code> and <code>entropy</code> set to uninitialized stack space. Tracing this call, you eventually arrive at a kernel function in <code>SceSblGcAuthMgrPcactForDriver</code> with the NID <code>0xB7AE58B9</code>. This call looks like the following
 
<source lang="c">
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]);
</source>
 
It appears that data from <code>aimgr_sm.self</code> ([[F00D Commands]]) along with <code>in</code>, <code>rtc_seconds</code> (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):
<source lang="c">
#define KIRK_CMD_ENCRYPT_IV_0 4
#define KIRK_CMD_ENCRYPT_IV_0 4
#define KIRK_CMD_DECRYPT_IV_0 7
#define KIRK_CMD_DECRYPT_IV_0 7
Line 870: Line 1,039:
}
}


static int generate_challenge(u8 mode, u8 *psid, u8 *entropy, u64 *rtc_tick, u8 *challenge, u8 *prng) {
static int generate_challenge(u8 mode, u8 *psid, u8 *epassword, 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_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 data_38DC[0x10] = { 0xCA, 0x0E, 0x20, 0x6E, 0xCE, 0xE6, 0xFB, 0x66, 0x68, 0x28, 0x65, 0x42, 0xEF, 0x4F, 0xF8, 0x8F };
Line 911: Line 1,080:


memcpy(challenge_work+0x20, work, 0x10);        // encrypted psid
memcpy(challenge_work+0x20, work, 0x10);        // encrypted psid
memcpy(challenge_work+0x30, rtc_tick, 0x8);     // rtc tick
memcpy(challenge_work+0x30, rtc_tick, 0x8);
memcpy(challenge_work+0x38, entropy+0x10, 0x20); // entropy, 32 bytes of epassword
memcpy(challenge_work+0x38, epassword+0x10, 0x20);


// fuseid
// fuseid
Line 929: Line 1,098:


// xor with data_38BC keys
// xor with data_38BC keys
for (i = 0; i < 0x60; i++) {
for (i = 0; i < 0x60; i++)
work[0x14+i] ^= data_38BC[i % 0x10];
work[0x14+i] ^= data_38BC[i % 0x10];
}


// encrypt data
// encrypt data
Line 939: Line 1,107:
// xor encrypted data with data_38BC keys
// xor encrypted data with data_38BC keys
for (i = 0; i < 0x60; i++) {
for (i = 0; i < 0x60; i++)
work[0x14+i] ^= data_38BC[i % 0x10];
work[0x14+i] ^= data_38BC[i % 0x10];
}


// build challenge string
// build challenge string
Line 974: Line 1,141:
=== How Sony Blocked Activation ===
=== 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.
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 Cmep and therefore spoofing it would require a Cmep hack.


=== How Hackers Bypassed The Block ===
=== How Hackers Bypassed The Block ===
Line 982: Line 1,149:
=== How Sony Unblocked Activation ===
=== 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...
Since May 2018, the challenge string in requests sent from PS Vita to PSN for Content and PSN Account (per-console) activations is not checked anymore. Strange...


I can think about 4 reasons:
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...
1) Sony wanted to fight ReStore by killing its purpose. In this case, they would have better patched the vulnerability...


2) Sony has done that by mistake. Impossible.
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.
3) Sony is working on a more secure PSN. We have an exemple: Sony removed ConsoleId checks on its servers for 3 months, around 2016-11-11, then restored the verification with even more securities. In the PS Vita case, they would have been quicker at fixing the 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.
4) Sony is working on a big change of PSN. This is very plausible since we discovered that they are adapting old PSN to work with a new "Account Id" because now people can change Sony Entertainment Network (PSN) ID. Moreover, on 2022-05-10, Sony released System Software version 3.74 to enforce the two-factor authentication system. This change also targets PS3 and PS4 and makes ReStore totally obsolete if it was needed again.


[[Category:ARM]]
[[Category:Kernel]]
[[Category:Modules]]
[[Category:Modules]]
[[Category:Kernel]]
[[Category:Library]]

Latest revision as of 21:04, 21 January 2024

SBL Game Card Auth Manager

Module

Version World Privilege
1.69-3.60 Non-secure Kernel

Libraries

Known NIDs

Version Name World Visibility NID
1.69-3.60 SceSblGcAuthMgrDrmBBForDriver Non-secure Kernel 0x1926B182
1.69 SceSblGcAuthMgrPcactForDriver Non-secure Kernel 0x0B8600A5
3.60 SceSblGcAuthMgrPcactForDriver Non-secure Kernel not present
1.69-3.60 SceSblGcAuthMgrMlnpsnlForDriver Non-secure Kernel 0x29ED0109
1.69 SceSblGcAuthMgrAdhocBBForDriver Non-secure Kernel 0x2EFA9203
3.60 SceSblGcAuthMgrAdhocBBForDriver Non-secure Kernel not present
1.69-3.60 SceSblGcAuthMgrPkgForDriver Non-secure Kernel 0x082FBA7D
1.69-3.60 SceSblGcAuthMgrSclkForDriver Non-secure Kernel 0xF24F760D
1.69-3.60 SceSblGcAuthMgrGcAuthForDriver Non-secure Kernel 0xC6627F5E
1.69-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 cmd56 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

224bit version of PSP Kirk 0x11 service

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
0.990-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
0.990-3.60 0x535B87BC

Returns error 0x808A040A.

get_5018_data

Version NID
0.990-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_safe_5018

Version NID
0.990-3.60 0x22FD5D23

Temp name was memcmp_5018_fast.

This function verifies that last 0x14 bytes of last response of size 0x34 from the game card (cmd56) are valid.

CMD56 response Buffer is obtained with KIRK command 0x20

For example it is called from SceAppMgr#sceAppMgrGameDataMount.

This is a timing safe memcmp. Xyz (talk) 10:02, 1 May 2017 (UTC)

int memcmp_safe_5018(char* in_data);

clear_sensitive_data

Version NID
0.990-3.60 0x812B2B5C

Clears some sensitive data.

Called after memcmp_safe_5018.

int clear_sensitive_data(int unk, int* value);

clear_sensitive_data_2

Version NID
0.990-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_2();

SceSblGcAuthMgrAdhocBBForDriver

Present on FW 1.69. Not present on FWs >= 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

This library is present on System Software versions 0.990.000-1.692.000. Not present since System Software version 1.80.

sceSblGcAuthMgrPcactActivationForDriver

Version NID
0.990.000-1.692.000 0x46B7AA5A

Calls get_aes_dec_key then SceNpDrm set_act_data.

typedef struct ScePcactUnkBuf { // size is 0x50 on FW 0.990
  short unk_0; // must be 0x211
  char mode;
  char reserved[0xD]; // must be zeroed
  char unk_10[0x40]; // might be keys generated from ConsoleId
} ScePcactUnkBuf;

typedef struct ScePcactActivationData { // size is 0x1090 on FW 0.990
  ScePcactUnkBuf unk_buf;
  char act_dat[0x1040];
} ScePcactActivationData;

int sceSblGcAuthMgrPcactActivationForDriver(const ScePcactActivationData *act_data, SceSize act_data_size);

sceSblGcAuthMgrPcactGetChallengeForDriver

Version NID
0.990.000-1.692.000 0xA3EEF3AD

Calls #SceSblGcAuthMgrPcactForDriver_B7AE58B9.

// entropy (epassword) size is 0x20 bytes
// challenge size is 0x80 bytes
int sceSblGcAuthMgrPcactGetChallengeForDriver(SceUID id, const char *entropy, char *challenge);

SceSblGcAuthMgrPcactForDriver_B7AE58B9

Version NID
0.990.000-1.692.000 0xB7AE58B9
typedef struct ScePcactCreateChallengeOpt {
    char data_offset;      // must be 0x10
    char reserved[15];     // must be zeroed
    char epassword[32];
} ScePcactCreateChallengeOpt;

// challenge size is 0x80 bytes
// prng size is 0x40 bytes
int SceSblGcAuthMgrPcactForDriver_B7AE58B9(SceUInt32 mode, ScePcactCreateChallengeOpt *pOpt, SceUInt64 *rtc_tick, void *challenge, void *prng);

get_aes_dec_key

Version NID
0.990.000-1.692.000 0xCA97CE1C

aes_dec_key is derived from act_data. prng seems to be a temporary work buffer.

// prng size is 0x40 bytes
// aes_dec_key size is 0x10 bytes
int get_aes_dec_key(const ScePcactActivationData *act_data, void *prng, void *aes_dec_key);

SceSblGcAuthMgrMlnpsnlForDriver

sceSblGcAuthMgrMlnpsnlAuth1ForDriver

Version NID
0.940-3.60 0xDABC01F5

sceSblGcAuthMgrMlnpsnlAuth2ForDriver

Version NID
0.940-3.60 0x296ABD68

SceSblGcAuthMgrPkgForDriver

sceSblGcAuthMgrPkgVryForDriver

Version NID
0.990-3.60 0xE459A9A8

Calls Secure_Modules_Functions#0x11_kirk_ecc160_verify KIRK command 0x11 to verify PKG ECDSA signature.

// pHash: sha1 hash of data (0x14 bytes)
// pSig: ECDSA signature (2 * 0x14 bytes)
int sceSblGcAuthMgrPkgVryForDriver(const char *pHash, const char *pSig);

SceSblGcAuthMgrSclkForDriver

Related to Secure clock.

sceSblGcAuthMgrSclkGetData1ForDriver

Version NID
0.990-3.60 0x11D5570B

AES256ECB encrypts a buffer made from a "genuine random number" followed by zeroes.

typedef struct SceSblGcAuthMgrSclkData1 { // size is 0x30
  int unk_0; // ex: 1
  int unk_4; // ex: 1
  int unk_8; // ex: 0
  int unk_C; // ex: 0
  char enc_data_0[0x10]; // seed = zeroes
  char enc_data_1[0x10]; // seed = hardcoded
} SceSblGcAuthMgrSclkData1;

int sceSblGcAuthMgrSclkGetData1ForDriver(SceSblGcAuthMgrSclkData1 *pData);

sceSblGcAuthMgrSclkSetData2ForDriver

Version NID
0.990-3.60 0xF723A9BA

Checks header, sha256, AES256ECB decrypts then sets some secure RTC.

typedef struct SceSblGcAuthMgrSclkData2 { // size is at least 0x30
  int unk_0; // ex: 1
  int unk_4; // ex: 1
  int unk_8; // ex: 0
  int unk_C; // ex: 0
  char enc_data_0[0x10];
  char enc_data_1[0x10];
  // more, maybe sha256
} SceSblGcAuthMgrSclkData2;

int sceSblGcAuthMgrSclkSetData2ForDriver(SceSblGcAuthMgrSclkData2 *pData);

SceSblGcAuthMgrGcAuthForDriver

cmd56_handshake

Version NID
3.60 0x68781760

This is a wrapper function that starts initialization subroutine through SceKernelThreadMgr#_sceKernelExtendKernelStackWideForDriver.

int cmd56_handshake(SceUInt32 keyid);

SceSblGcAuthMgrPsmactForDriver

get_act_data

Version NID
0.931.010-1.692.000 not present
1.800.071-3.740.011 0x39222A58

Executes KIRK command 0x1000B 19.

// data is of size 0x80
int get_act_data(void* data);

SceSblGcAuthMgrMsSaveBBForDriver

sceSblGcAuthMgrMsSaveBBCipherInitForDriver

Version NID
3.60 0x3C185A67

AES encrypts with null IV using a Kirk command.

sceSblGcAuthMgrMsSaveBBMacInitForDriver

Version NID
3.60 0x4A249828
int sceSblGcAuthMgrMsSaveBBMacInitForDriver(void *pDst, SceUInt32 initValue);

sceSblGcAuthMgrMsSaveBBMacUpdateForDriver

Version NID
3.60 0x79A9BE44

AES encrypts a 0x800 buffer.

sceSblGcAuthMgrMsSaveBBCipherFinalForDriver

Version NID
3.60 0x805C860B

sceSblGcAuthMgrMsSaveBBMacFinalForDriver

Version NID
3.60 0x8E6626A0

sceSblGcAuthMgrMsSaveBBCipherUpdateForDriver

Version NID
3.60 0xF66D5F76

AES decrypts a 0x800 buffer then AES decrypts with null IV using a Kirk command.

SceSblGcAuthMgr

_sceSblGcAuthMgrPcactActivation

Version NID
0.990-3.60 0x032E7CEA
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.03 not present
1.69-3.60 0x0AC64154

Returns MediaIdType01 by using Kirk command 0x23 on a global buffer.

typedef struct SceMediaIdType01 {
  char enc_data[0x10]; // encrypted data
  char enc_data_cmac[0x10]; // CMAC of encrypted data
} SceMediaIdType01;

int _sceSblGcAuthMgrGetMediaIdType01(SceMediaIdType01 **pMediaId);

_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
typedef struct SceSblGcAuthMgrPkgVryInfo { // size is 0x10
  SceSize hashSize; // ex: 0x14
  SceSize sigSize; // ex: 0x28
  SceUInt64 reserved;
} SceSblGcAuthMgrPkgVryInfo;

// pHash: sha1 hash of data (0x14 bytes)
// pSig: ECDSA signature (2 * 0x14 bytes)
int _sceSblGcAuthMgrPkgVry(const char *pHash, const char *pSig, SceSblGcAuthMgrPkgVryInfo *pInfo);

_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.740.011 0x98153286
typedef struct ScePcactGetChallengeOpt { // size is 0x10 on FWs 0.990-3.740.011
  SceSize epasswordSize; // Maximum size is 0x20 bytes
  SceSize challengeSize; // Maximum size is 0x80 bytes
  char reserved[8];
} ScePcactGetChallengeOpt;

int _sceSblGcAuthMgrPcactGetChallenge(SceUInt32 id, const char *epassword, 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

gcauthmgr_sm calls to Kirk commands in cmep

The use of os0:sm/gcauthmgr_sm.self is to support the new generation of Kirk. It uses a similar input structure to the original Kirk on the PSP.

PSP Kirk support

4, 7, 0xC, 0xD, 0xE, 0x10, 0x11, 0x12 are the classic PSP Kirk services supported by gcauthmgr_sm. However, keys and seeds are sometimes different and look similar to PS3 crypto.

New PS Vita Kirk services

0x14-0x19, 0x1B-0x23 are the new Kirk services supported by gcauthmgr_sm. Most are just 224bit versions of original Kirk commands.

  • 0x14 is the 224bit version of ECDSA key pair gen (Kirk command 0xC). 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 the 224bit version of pseudo random number generator (Kirk command 0xE). It will return 0x1C bytes of random data into the buffer.
  • 0x17-0x19 are the 224bit ECDSA versions of PSP's 160bit Kirk commands 0x10-0x12.
  • 0x1B-0x23 have no equivalent on PSP Kirk but are maybe also present on PS3

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#sceSblGcAuthMgrPcactGetChallenge. It is called with id = 0 and epassword set to uninitialized stack space. Tracing this call, you eventually arrive at SceSblGcAuthMgr#SceSblGcAuthMgrPcactForDriver_B7AE58B9. It appears that data from aimgr_sm.self (see Secure Modules Functions) along with pOpt, rtc_tick (the RTC in seconds), DMAC engine, and maybe other data are entangled together into a 0x70-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 (almost same code as in PS 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 *epassword, 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);
	memcpy(challenge_work+0x38, epassword+0x10, 0x20);

	// 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 Cmep and therefore spoofing it would require a Cmep 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 PS Vita to PSN for Content and PSN Account (per-console) activations is not checked anymore. Strange...

I can think about 4 reasons:

1) Sony wanted to fight ReStore by killing its purpose. In this 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: Sony removed ConsoleId checks on its servers for 3 months, around 2016-11-11, then restored the verification with even more securities. In the PS Vita case, they would have been quicker at fixing the challenge if that was for security.

4) Sony is working on a big change of PSN. This is very plausible since we discovered that they are adapting old PSN to work with a new "Account Id" because now people can change Sony Entertainment Network (PSN) ID. Moreover, on 2022-05-10, Sony released System Software version 3.74 to enforce the two-factor authentication system. This change also targets PS3 and PS4 and makes ReStore totally obsolete if it was needed again.