Sealedkey / pfsSKKey: Difference between revisions

From PS4 Developer wiki
Jump to navigation Jump to search
No edit summary
Line 53: Line 53:


== De/En -Crypting ==
== De/En -Crypting ==
Can be decrypted by frindly asking the OS to do it for you. You will need kernel rights to be able to ask the PS4 for it.
Can be decrypted by friendly asking the OS to do it for you. You will need kernel rights to be able to ask the PS4 for it.
<source lang="c">
<source lang="c">
  /* Decryption */  
  /* Decryption */  

Revision as of 14:45, 23 April 2017

This key can be found on different places and will be used for eg. SaveGame or Trophy Data decryption and encryption.

Paths

Kind Path
Trophys /user/home/user Id/trophy/data/sce_trop/sealedkey
SaveGames /user/home/user Id/title Id/save data directory/sce_sys/

Structure

- size always 96 bytes

From To Description
00 07 MAGIC ("pfsSKKey") (?playstation file system sealed key key?)
08 0F Category (game=1 or version ?)
10 1F IV (16 bytes)
20 3F Encrypted key (32 bytes)
40 5F SHA-256 (32 bytes)

C

 typedef struct sealedkey_t {
     const unsigned char MAGIC[8];
     const unsigned char CAT[8];
     const unsigned char IV[16];
     const unsigned char KEY[32];
     const unsigned char SHA256[32];
 } PfsSKKey;

CSharp

 protected internal struct sealedkey {
     internal static byte[] MAGIC = new byte[8];
     internal static byte[] CAT = new byte[8];
     internal static byte[] IV = new byte[16];
     internal static byte[] KEY = new byte[32];
     internal static byte[] SHA256 = new byte[32];
 }

Note: You can't use a const byte[] defination in C#. It need to be a static byte[].

De/En -Crypting

Can be decrypted by friendly asking the OS to do it for you. You will need kernel rights to be able to ask the PS4 for it.

 /* Decryption */ 
 #define foreach(item, array) \
     for (int keep = 1, \
              count = 0, \
              size = sizeof(array) / sizeof*(array); \
          keep && count != size; \
          keep = !keep, count++) \
         for (item = (array) + count; keep; keep = !keep)
 
 typedef unsigned char byte;              /* byte defination for c/c++ */
 byte PFSK_IDENT[8] = "pfsSKKey";
 byte VERSION[8] = "\x01\x00\x00\x00\x00\x00\x00\x00"
 const char USER1 = "10000000";
 const char usb0 = "/mnt/usb0/";
 const char usb1 = "/mnt/usb1/";
 const char pfs = "dec_pfsSK.Key";
 const char home = "/user/home/";
 const char tropkey = "/trophy/data/sce_trop/sealedkey";
 char usb_error = "[-] ERROR: Can't access usb0 nor usb1!\n[-] Will return now to caller.\n"
 char usb0path[(strlen(usb0) + strlen(pfs))];
 char usb1path[strlen(usb0path)];
 
 /* Get's the encrypted sealed key based on user id */
 int get_pfsSKKey(byte *buffer, const char *userID, char path) {
     char toOpen[(strlen(home) + strlen(userID) + strlen(path))];
 
     sprintf(toOpen, home, userID, path)
 
     FILE *pfskey = fopen(toOpen, "r"); 
 
     if (!pfskey) return NULL;
  
     fread(buffer, 96, 1, pfskey);
     fclose(pfskey);
     return 1;
 }
 
 /* Dump the sealedkey. Send over tcp and save to file */
 int dumpDecryptedSealedKey(int to) {
     if (to < 0 || to > 1) return -2;
 
     /* First load the sealedkey into a buffer */
     PfsSKKEy enc;
     if (!get_pfsSKKey(&enc, USER1, tropkey)) {
         printf("[-] Can not load the sealed key!\n");
         return -1;
     }
 
     /* Let's check the pfsSKKEy */
     if (enc->MAGIC == PFSK_IDENT && enc->CAT == VERSION) {
         printf("[+] Magic and version ok!\n[+] sk IV = ");
         foreach(byte *val, &enc->IV) printf("%02X", *val);
 
         printf("\n[+] sk KEY = ");
         foreach(byte *val, enc->KEY) printf("%02X", *val);
 
         printf("\n[+] sk Key-SHA256 = ");
         foreach(byte *val, sk->SHA256) printf("%02X", *val);
         printf("\n");
         
     }
     else return -4;
 
     /* Now decrypt it */
     byte dec[16];
 
     int i;
     if (!(i = kernel.sceSblSsDecryptSealedKey(&enc, &dec))) {
         printf("[-] Error!\n[-] sceSblSsDecryptSealedKey returned %d\n", i);
         return -1;
     }
     printf("[+] sceSblSsDecryptSealedKey returned %d\n", i);
 
     if (!to) { /* Print it out */
         printf("[+] Your decrypted sealedkey = ");
 
         foreach(byte *val, &dec) printf("%02X", *val);
 
         printf("\n");
         return 1;
     }
     else { /* Saving to file */
         printf("[+] Will try to save to file...");
	    
         sprintf(usb0path, usb0, pfs);
         sprintf(usb1path, usb1, pfs);
 
         FILE *dump = fopen(usb0path, "w");
	  
         if (!dump) {
             dump = fopen(usb1path, "w");
             if (!dump) {
                 printf("fail!\n%s", usb_error);
                 return -3;
             }
         }
 
         fwrite(&dec, 16, 1, dump);
         printf("done!\n");
         fclose(dump);
         return 1;
     }
 }