Advertisement
Evilnat

make_rif.c

Dec 29th, 2024 (edited)
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.64 KB | Source Code | 0 0
  1. #include <lv2/libc.h>
  2. #include <lv2/io.h>
  3. #include <lv2/error.h>
  4. #include <lv2/security.h>
  5. #include <lv2/ctrl.h>
  6. #include "common.h"
  7. #include "mappath.h"
  8. #include "modulespatch.h"
  9. #include "ps3mapi_core.h"
  10. #include "make_rif.h"
  11.  
  12. #define ACCOUNTID                       1
  13. #define READ                            0
  14.  
  15. #define XREGISTRY_FILE                  "/dev_flash2/etc/xRegistry.sys"
  16.  
  17. static uint8_t empty[0x10] =
  18. {
  19.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  20.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  21. };
  22.  
  23.  
  24. unsigned char RAP_KEY[] =  { 0x86, 0x9F, 0x77, 0x45, 0xC1, 0x3F, 0xD8, 0x90, 0xCC, 0xF2, 0x91, 0x88, 0xE3, 0xCC, 0x3E, 0xDF };
  25. unsigned char RAP_PBOX[] = { 0x0C, 0x03, 0x06, 0x04, 0x01, 0x0B, 0x0F, 0x08, 0x02, 0x07, 0x00, 0x05, 0x0A, 0x0E, 0x0D, 0x09 };
  26. unsigned char RAP_E1[] =   { 0xA9, 0x3E, 0x1F, 0xD6, 0x7C, 0x55, 0xA3, 0x29, 0xB7, 0x5F, 0xDD, 0xA6, 0x2A, 0x95, 0xC7, 0xA5 };
  27. unsigned char RAP_E2[] =   { 0x67, 0xD4, 0x5D, 0xA3, 0x29, 0x6D, 0x00, 0x6A, 0x4E, 0x7C, 0x53, 0x7B, 0xF5, 0x53, 0x8C, 0x74 };
  28.  
  29. uint32_t userID;
  30. uint8_t skip_existing_rif = 0;
  31. uint8_t account_id[0x10];
  32.  
  33. static int xreg_data(char *value)
  34. {
  35.     int fd, result = -1;
  36.     uint16_t offset = 0;
  37.     uint64_t read, seek;    
  38.  
  39.     if(cellFsOpen(XREGISTRY_FILE, CELL_FS_O_RDWR, &fd, 0666, NULL, 0) != SUCCEEDED)
  40.         return result;
  41.  
  42.     char *buffer = malloc(0x2A);    
  43.  
  44.     if(!buffer)
  45.         return result;
  46.  
  47.     // Get offset
  48.     for(int i = 0; i < 0x10000; i++)
  49.     {      
  50.         cellFsLseek(fd, i, SEEK_SET, &seek);
  51.         cellFsRead(fd, buffer, 0x31 + 1, &read);
  52.  
  53.         // Found offset
  54.         if(strcmp(buffer, value) == 0)
  55.         {
  56.             offset = i - 0x15;
  57.             uint8_t *data = NULL;
  58.  
  59.             // Search value from value table
  60.             for(int i = 0x10000; i < 0x15000; i++)
  61.             {
  62.                 data = (uint8_t *) malloc(0x17);
  63.  
  64.                 if(!data)
  65.                 {
  66.                     free(buffer);
  67.                     return result;
  68.                 }
  69.  
  70.                 cellFsLseek(fd, i, SEEK_SET, &seek);
  71.                 cellFsRead(fd, data, 0x17, &read);
  72.                
  73.                 // Found value
  74.                 if (memcmp(data, &offset, 2) == 0 && data[4] == 0x00 && data[5] == 0x11 && data[6] == 0x02)
  75.                 {      
  76.                     result = 0;  
  77.  
  78.                     memcpy(&account_id, data + 7, 0x10);
  79.  
  80.                     if(memcmp(data + 7, empty, 0x10) != SUCCEEDED)                        
  81.                         result = 1;                                                                    
  82.  
  83.                     free(data);
  84.                     free(buffer);
  85.                     cellFsClose(fd);
  86.                    
  87.                     return result;
  88.                 }
  89.  
  90.                 free(data);
  91.             }
  92.         }
  93.     }
  94.  
  95.     free(buffer);
  96.     cellFsClose(fd);    
  97.  
  98.     return result;
  99. }
  100.  
  101. static void get_rif_key(unsigned char* rap, unsigned char* rif)
  102. {
  103.     int i;
  104.     int round;
  105.  
  106.     unsigned char key[0x10];
  107.     unsigned char iv[0x10];
  108.     memset(key, 0, 0x10);
  109.     memset(iv, 0, 0x10);
  110.  
  111.     // Initial decrypt.
  112.     aescbccfb_dec(key, rap, 0x10, RAP_KEY, 0x80, iv);
  113.     memset(iv, 0, 0x10);
  114.  
  115.     // rap2rifkey round.
  116.     for (round = 0; round < 5; ++round)
  117.     {
  118.         for (i = 0; i < 16; ++i)
  119.         {
  120.             int p = RAP_PBOX[i];
  121.             key[p] ^= RAP_E1[p];
  122.         }
  123.  
  124.         for (i = 15; i >= 1; --i)
  125.         {
  126.             int p = RAP_PBOX[i];
  127.             int pp = RAP_PBOX[i - 1];
  128.             key[p] ^= key[pp];
  129.         }
  130.  
  131.         int o = 0;
  132.  
  133.         for (i = 0; i < 16; ++i)
  134.         {
  135.             int p = RAP_PBOX[i];
  136.             unsigned char kc = key[p] - o;
  137.             unsigned char ec2 = RAP_E2[p];
  138.             if (o != 1 || kc != 0xFF)
  139.             {
  140.                 o = kc < ec2 ? 1 : 0;
  141.                 key[p] = kc - ec2;
  142.             }
  143.             else if (kc == 0xFF)           
  144.                 key[p] = kc - ec2;         
  145.             else           
  146.                 key[p] = kc;           
  147.         }
  148.     }
  149.  
  150.     memcpy(rif, key, 0x10);
  151. }
  152.  
  153. static void read_act_dat_and_make_rif(uint8_t *rap, uint8_t *act_dat, const char *content_id, const char *rif_path)
  154. {
  155.     int fd;
  156.  
  157.     if(cellFsOpen(rif_path, CELL_FS_O_WRONLY | CELL_FS_O_CREAT | CELL_FS_O_TRUNC, &fd, 0666, NULL, 0) == SUCCEEDED)
  158.     {
  159.         uint8_t idps_const[0x10]    = { 0x5E, 0x06, 0xE0, 0x4F, 0xD9, 0x4A, 0x71, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
  160.         uint8_t rif_key_const[0x10] = { 0xDA, 0x7D, 0x4B, 0x5E, 0x49, 0x9A, 0x4F, 0x53, 0xB1, 0xC1, 0xA1, 0x4A, 0x74, 0x84, 0x44, 0x3B };
  161.  
  162.         uint8_t *rif = ALLOC_RIF_BUFFER;
  163.         uint8_t *key_index = rif + 0x40;
  164.         uint8_t *rif_key = rif + 0x50;
  165.         memset(rif, 0, 0x70);
  166.  
  167.         get_rif_key(rap, rif_key); //convert rap to rifkey (klicensee)
  168.  
  169.         uint8_t *iv = rif + 0x60;
  170.         aescbccfb_enc(idps_const, idps_const, 0x10, (void*)PS3MAPI_IDPS_2, IDPS_KEYBITS, iv);
  171.  
  172.         uint8_t *act_dat_key = rap;
  173.         memcpy(act_dat_key, act_dat + 0x10, 0x10);
  174.  
  175.         memset(iv, 0, 0x10);
  176.         aescbccfb_dec(act_dat_key, act_dat_key, 0x10, idps_const, IDPS_KEYBITS, iv);
  177.  
  178.         memset(iv, 0, 0x10);
  179.         aescbccfb_enc(rif_key, rif_key, 0x10, act_dat_key, ACT_DAT_KEYBITS, iv);
  180.  
  181.         memset(iv, 0, 0x10);
  182.         aescbccfb_enc(key_index, key_index, 0x10, rif_key_const, RIF_KEYBITS, iv);
  183.  
  184.         const uint32_t version_number = 1;
  185.         const uint32_t license_type = 0x00010002;
  186.         const uint64_t timestamp = 0x000001619BF6DDCA;
  187.         const uint64_t expiration_time = 0;
  188.  
  189.         memcpy(rif,        &version_number,  4); // 0x00 version_number
  190.         memcpy(rif + 0x04, &license_type,    4); // 0x04 license_type
  191.         memcpy(rif + 0x08, act_dat + 0x8,    8); // 0x08 account_id
  192.         memcpy(rif + 0x10, content_id,    0x24); // 0x10 content_id
  193.                                                  // 0x40 encrypted key index (Used for choosing act.dat key)
  194.                                                  // 0x50 encrypted rif_key
  195.         memcpy(rif + 0x60, &timestamp,       8); // 0x60 timestamp
  196.         memcpy(rif + 0x68, &expiration_time, 8); // 0x68 expiration time
  197.  
  198.         uint64_t size;
  199.         memset(rif + 0x70, 0x11, 0x28);          // 0x70 ECDSA Signature
  200.         cellFsWrite(fd, rif, 0x98, &size);
  201.         cellFsClose(fd);
  202.     }
  203. }
  204.  
  205. int create_act_dat(const char *userid)
  206. {
  207.     int fd;
  208.     uint64_t size;
  209.     char full_path[120], exdata_dir[120];
  210.     CellFsStat stat;
  211.  
  212.     //DPRINTF("Creating act.dat for userID %s...\n", userid);
  213.  
  214.     uint8_t timedata[0x10] =
  215.     {
  216.         0x00, 0x00, 0x01, 0x2F, 0x3F, 0xFF, 0x00, 0x00,
  217.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  218.     };
  219.  
  220.     const uint64_t header = 0x0000000100000002;
  221.  
  222.     uint64_t accountID = (uint64_t)strtoull((const char*)account_id, NULL, 16);
  223.     accountID = SWAP64(accountID);
  224.    
  225.     uint8_t *actdat = malloc(0x1038);  
  226.  
  227.     if(!actdat)
  228.         return 1;
  229.    
  230.     memset(actdat, 0x11, 0x1038);
  231.     memcpy(actdat, &header, 8);
  232.     memcpy(actdat + 8, &accountID, 8);
  233.     memcpy(actdat + 0x870, timedata, 0x10);
  234.  
  235.     sprintf(exdata_dir, "/dev_hdd0/home/%s/exdata", userid);
  236.  
  237.     if(cellFsStat(exdata_dir, &stat) != SUCCEEDED)             
  238.         cellFsMkdir(exdata_dir, 0777);     
  239.  
  240.     sprintf(full_path, "%s/act.dat", exdata_dir);
  241.  
  242.     cellFsOpen(full_path, CELL_FS_O_WRONLY | CELL_FS_O_CREAT | CELL_FS_O_TRUNC, &fd, 0666, NULL, 0);
  243.     cellFsWrite(fd, actdat, 0x1038, &size);
  244.     cellFsClose(fd);
  245.  
  246.     free(actdat);
  247.  
  248.     return SUCCEEDED;
  249. }
  250.  
  251. void make_rif(const char *path)
  252. {      
  253.     char buffer[120];  
  254.     int path_len = strlen(path);   
  255.    
  256.     if(!strncmp(path, "/dev_hdd0/home/", 15) && !strcmp(path + path_len - 4, ".rif"))
  257.     {      
  258.         int act_dat_found = 0;
  259.         int fd;
  260.         CellFsStat stat;       
  261.        
  262.         DPRINTF("open_path_hook: %s (looking for rap)\n", path);
  263.  
  264.         char *content_id = ALLOC_CONTENT_ID;
  265.         memset(content_id, 0, 0x25);
  266.         strncpy(content_id, strrchr(path, '/') + 1, 0x24);
  267.  
  268.         char *rap_path = ALLOC_PATH_BUFFER;
  269.  
  270.         uint8_t is_ps2_classic = !strncmp(content_id, "2P0001-PS2U10000_00-0000111122223333", 0x24);
  271.         uint8_t is_psp_launcher = !strncmp(content_id, "UP0001-PSPC66820_00-0000111122223333", 0x24);
  272.  
  273.         char userid[8];
  274.         strncpy(userid, path + 15, 8);
  275.         userid[8] = '\0';      
  276.  
  277.         if(!is_ps2_classic && !is_psp_launcher)
  278.         {
  279.             CellFsStat stat;
  280.             const char *ext = "rap";
  281.  
  282.             // Support for rap and RAP extension (By aldostools)
  283.             for(uint8_t i = 0; i < 2; i++)
  284.             {
  285.                 sprintf(rap_path, "/dev_usb000/exdata/%36s.%s", content_id, ext);
  286.  
  287.                 if(cellFsStat(rap_path, &stat) != SUCCEEDED)
  288.                     rap_path[10] = '1'; //dev_usb001
  289.                 if(cellFsStat(rap_path, &stat) != SUCCEEDED)
  290.                     sprintf(rap_path, "/dev_hdd0/exdata/%36s.%s", content_id, ext);
  291.  
  292.                 if(cellFsStat(rap_path, &stat) != SUCCEEDED)
  293.                     ext = "RAP";
  294.                 else
  295.                     break;
  296.             }
  297.         }      
  298.  
  299.         char rap_bin_dir[120];
  300.         sprintf(rap_bin_dir, "/dev_hdd0/home/%s/exdata/rap.bin", userid);
  301.         cellFsStat(rap_bin_dir, &stat);
  302.  
  303.         if(is_ps2_classic || is_psp_launcher || cellFsOpen((!rap_mode) ? rap_path : rap_bin_dir, CELL_FS_O_RDONLY, &fd, 0666, NULL, 0) == SUCCEEDED)
  304.         {
  305.             uint64_t nread = 0;
  306.             uint8_t rap[0x10] = { 0xF5, 0xDE, 0xCA, 0xBB, 0x09, 0x88, 0x4F, 0xF4, 0x02, 0xD4, 0x12, 0x3C, 0x25, 0x01, 0x71, 0xD9 };
  307.  
  308.             if(!is_ps2_classic && !is_psp_launcher)
  309.             {
  310.                 if(!rap_mode)
  311.                 {
  312.                     DPRINTF("rap_path: %s output: %s\n", rap_path, path);
  313.                     cellFsRead(fd, rap, 0x10, &nread);
  314.                 }
  315.                 else
  316.                 {                      
  317.                     // rap2bin-bin2rap by esc0rtd3w
  318.                     // All credits goes to him
  319.                     int MAGIC_NUMBER = 0xFAF0FAF0;
  320.                     uint8_t buffer[0x50];
  321.  
  322.                     //DPRINTF("loading license from rap.bin...\n");
  323.  
  324.                     while(cellFsRead(fd, buffer, 0x50, &nread) == SUCCEEDED)
  325.                     {
  326.                         if((int)!nread)
  327.                             break;
  328.  
  329.                         if(memcmp(buffer, &MAGIC_NUMBER, 4) == SUCCEEDED)
  330.                         {                        
  331.                             if(memcmp(buffer + 0x10, content_id, 0x24) == SUCCEEDED)
  332.                             {
  333.                                 memcpy(rap, buffer + 0x40, 0x10);
  334.                                 DPRINTF("loaded license from rap.bin for %s\n", content_id);
  335.                                 break;
  336.                             }
  337.                         }
  338.                     }
  339.                 }
  340.                
  341.                 cellFsClose(fd);
  342.             }              
  343.  
  344.             // Search act.dat in home dirs
  345.             for(int i = 1; i < 100; i++)
  346.             {
  347.                 sprintf(buffer, ACTDAT_PATH, i);
  348.                
  349.                 if(cellFsStat(buffer, &stat) == SUCCEEDED)
  350.                 {
  351.                     //DPRINTF("Found act.dat in %08d\n", i);
  352.                     act_dat_found = 1;
  353.                     break;
  354.                 }  
  355.             }                      
  356.  
  357.             sprintf(buffer, ACCOUNTID_VALUE, userid);
  358.            
  359.             if(!act_dat_found && xreg_data(buffer))
  360.                 create_act_dat(userid);
  361.  
  362.             act_dat_found = 0;
  363.  
  364.             // Skip the creation of rif license if it already exists - By aldostool
  365.             if(skip_existing_rif && cellFsStat(path, &stat) == SUCCEEDED)          
  366.                 return;        
  367.            
  368.             char *act_path = ALLOC_PATH_BUFFER;
  369.             memset(act_path, 0, 0x50);
  370.             strncpy(act_path, path, strrchr(path, '/') - path);
  371.             strcpy(act_path + strlen(act_path), "/act.dat\0");
  372.  
  373.             DPRINTF("act_path: %s content_id: %s\n", act_path, content_id);
  374.  
  375.             if(cellFsOpen(act_path, CELL_FS_O_RDONLY, &fd, 0666, NULL, 0) == SUCCEEDED)
  376.             {
  377.                 uint8_t *act_dat = ALLOC_ACT_DAT;
  378.                 cellFsRead(fd, act_dat, 0x20, &nread); // size: 0x1038 but only first 0x20 are used to make rif
  379.                 cellFsClose(fd);
  380.  
  381.                 if(nread == 0x20)
  382.                 {
  383.                     char *rif_path = ALLOC_PATH_BUFFER;
  384.                     sprintf(rif_path, "/%s", path);
  385.                     read_act_dat_and_make_rif(rap, act_dat, content_id, rif_path);
  386.                 }
  387.             }          
  388.         }
  389.     }
  390. }
  391.  
Tags: Cobra 8.5
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement