PS2SDK
PS2 Homebrew Libraries
libsecr.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <kernel.h>
4 #include <sifrpc.h>
5 #include <iopcontrol.h>
6 
7 #include "libsecr.h"
8 #include "secrsif.h"
9 
10 static SifRpcClientData_t SifRpcClient01;
11 static SifRpcClientData_t SifRpcClient02;
12 static SifRpcClientData_t SifRpcClient03;
13 static SifRpcClientData_t SifRpcClient04;
14 static SifRpcClientData_t SifRpcClient05;
15 static SifRpcClientData_t SifRpcClient06;
16 static SifRpcClientData_t SifRpcClient07;
17 
18 static unsigned char RpcBuffer[0x1000] ALIGNED(64);
19 
20 #define _printf(args...) // printf(args)
21 
22 int SecrInit(void)
23 {
25  SecrDeinit();
26 
27  sceSifInitRpc(0);
28 
29  nopdelay();
30  while (sceSifBindRpc(&SifRpcClient01, 0x80000A01, 0) < 0 || SifRpcClient01.server == NULL) {
31  _printf("libsecr: bind failed\n");
32  }
33 
34  nopdelay();
35  while (sceSifBindRpc(&SifRpcClient02, 0x80000A02, 0) < 0 || SifRpcClient02.server == NULL) {
36  _printf("libsecr: bind failed\n");
37  }
38 
39  nopdelay();
40  while (sceSifBindRpc(&SifRpcClient03, 0x80000A03, 0) < 0 || SifRpcClient03.server == NULL) {
41  _printf("libsecr: bind failed\n");
42  }
43 
44  nopdelay();
45  while (sceSifBindRpc(&SifRpcClient04, 0x80000A04, 0) < 0 || SifRpcClient04.server == NULL) {
46  _printf("libsecr: bind failed\n");
47  }
48 
49  nopdelay();
50  while (sceSifBindRpc(&SifRpcClient05, 0x80000A05, 0) < 0 || SifRpcClient05.server == NULL) {
51  _printf("libsecr: bind failed\n");
52  }
53 
54  nopdelay();
55  while (sceSifBindRpc(&SifRpcClient06, 0x80000A06, 0) < 0 || SifRpcClient06.server == NULL) {
56  _printf("libsecr: bind failed\n");
57  }
58 
59  nopdelay();
60  while (sceSifBindRpc(&SifRpcClient07, 0x80000A07, 0) < 0 || SifRpcClient07.server == NULL) {
61  _printf("libsecr: bind failed\n");
62  }
63 
64  return 1;
65 }
66 
67 void SecrDeinit(void)
68 {
69  memset(&SifRpcClient01, 0, sizeof(SifRpcClientData_t));
70  memset(&SifRpcClient02, 0, sizeof(SifRpcClientData_t));
71  memset(&SifRpcClient03, 0, sizeof(SifRpcClientData_t));
72  memset(&SifRpcClient04, 0, sizeof(SifRpcClientData_t));
73  memset(&SifRpcClient05, 0, sizeof(SifRpcClientData_t));
74  memset(&SifRpcClient06, 0, sizeof(SifRpcClientData_t));
75  memset(&SifRpcClient07, 0, sizeof(SifRpcClientData_t));
76 }
77 
78 int SecrDownloadHeader(int port, int slot, void *buffer, SecrBitTable_t *BitTable, s32 *pSize)
79 {
80  int result;
81 
82  ((struct SecrSifDownloadHeaderParams *)RpcBuffer)->port = port;
83  ((struct SecrSifDownloadHeaderParams *)RpcBuffer)->slot = slot;
84  memcpy(((struct SecrSifDownloadHeaderParams *)RpcBuffer)->buffer, buffer, sizeof(((struct SecrSifDownloadHeaderParams *)RpcBuffer)->buffer));
85 
86  if (sceSifCallRpc(&SifRpcClient01, 1, 0, RpcBuffer, sizeof(RpcBuffer), RpcBuffer, sizeof(RpcBuffer), NULL, NULL) < 0) {
87  _printf("sceSecrDownloadHeader: rpc error\n");
88  result = 0;
89  } else {
90  memcpy(BitTable, &((struct SecrSifDownloadHeaderParams *)RpcBuffer)->BitTable, ((struct SecrSifDownloadHeaderParams *)RpcBuffer)->size);
91  // BUG: pSize doesn't seem to be filled in within the Sony original.
92  if (pSize != NULL)
93  *pSize = ((struct SecrSifDownloadHeaderParams *)RpcBuffer)->size;
94  result = ((struct SecrSifDownloadHeaderParams *)RpcBuffer)->result;
95  }
96 
97  return result;
98 }
99 
100 int SecrDownloadBlock(void *src, unsigned int size)
101 {
102  int result;
103 
104  memcpy(((struct SecrSifDownloadBlockParams *)RpcBuffer)->buffer, src, sizeof(((struct SecrSifDownloadBlockParams *)RpcBuffer)->buffer));
105  ((struct SecrSifDownloadBlockParams *)RpcBuffer)->size = size;
106 
107  if (sceSifCallRpc(&SifRpcClient02, 1, 0, RpcBuffer, sizeof(RpcBuffer), RpcBuffer, sizeof(RpcBuffer), NULL, NULL) < 0) {
108  _printf("sceSecrDownloadBlock: rpc error\n");
109  result = 0;
110  } else {
111  result = ((struct SecrSifDownloadBlockParams *)RpcBuffer)->result;
112  }
113 
114  return result;
115 }
116 
117 int SecrDownloadGetKbit(int port, int slot, void *kbit)
118 {
119  int result;
120 
121  ((struct SecrSifDownloadGetKbitParams *)RpcBuffer)->port = port;
122  ((struct SecrSifDownloadGetKbitParams *)RpcBuffer)->slot = slot;
123 
124  if (sceSifCallRpc(&SifRpcClient03, 1, 0, RpcBuffer, sizeof(RpcBuffer), RpcBuffer, sizeof(RpcBuffer), NULL, NULL) < 0) {
125  _printf("sceSecrDownloadGetKbit: rpc error\n");
126  result = 0;
127  } else {
128  memcpy(kbit, ((struct SecrSifDownloadGetKbitParams *)RpcBuffer)->kbit, sizeof(((struct SecrSifDownloadGetKbitParams *)RpcBuffer)->kbit));
129  result = ((struct SecrSifDownloadGetKbitParams *)RpcBuffer)->result;
130  }
131 
132  return result;
133 }
134 
135 int SecrDownloadGetKc(int port, int slot, void *kc)
136 {
137  int result;
138 
139  ((struct SecrSifDownloadGetKcParams *)RpcBuffer)->port = port;
140  ((struct SecrSifDownloadGetKcParams *)RpcBuffer)->slot = slot;
141 
142  if (sceSifCallRpc(&SifRpcClient04, 1, 0, RpcBuffer, sizeof(RpcBuffer), RpcBuffer, sizeof(RpcBuffer), NULL, NULL) < 0) {
143  _printf("sceSecrDownloadGetKc: rpc error\n");
144  result = 0;
145  } else {
146  memcpy(kc, ((struct SecrSifDownloadGetKcParams *)RpcBuffer)->kc, sizeof(((struct SecrSifDownloadGetKcParams *)RpcBuffer)->kc));
147  result = ((struct SecrSifDownloadGetKcParams *)RpcBuffer)->result;
148  }
149 
150  return result;
151 }
152 
153 int SecrDownloadGetICVPS2(void *icvps2)
154 {
155  int result;
156 
157  if (sceSifCallRpc(&SifRpcClient05, 1, 0, RpcBuffer, sizeof(RpcBuffer), RpcBuffer, sizeof(RpcBuffer), NULL, NULL) < 0) {
158  _printf("sceSecrDownloadGetICVPS2: rpc error\n");
159  result = 0;
160  } else {
161  memcpy(icvps2, ((struct SecrSifDownloadGetIcvps2Params *)RpcBuffer)->icvps2, sizeof(((struct SecrSifDownloadGetIcvps2Params *)RpcBuffer)->icvps2));
162  result = ((struct SecrSifDownloadGetIcvps2Params *)RpcBuffer)->result;
163  }
164 
165  return result;
166 }
167 
168 int SecrDiskBootHeader(void *buffer, SecrBitTable_t *BitTable, s32 *pSize)
169 {
170  int result;
171 
172  memcpy(((struct SecrSifDiskBootHeaderParams *)RpcBuffer)->buffer, buffer, sizeof(((struct SecrSifDiskBootHeaderParams *)RpcBuffer)->buffer));
173 
174  if (sceSifCallRpc(&SifRpcClient06, 1, 0, RpcBuffer, sizeof(RpcBuffer), RpcBuffer, sizeof(RpcBuffer), NULL, NULL) < 0) {
175  _printf("sceSecrDiskBootHeader: rpc error\n");
176  result = 0;
177  } else {
178  memcpy(BitTable, &((struct SecrSifDiskBootHeaderParams *)RpcBuffer)->BitTable, ((struct SecrSifDiskBootHeaderParams *)RpcBuffer)->size);
179  // BUG: pSize doesn't seem to be filled in within the Sony original.
180  if (pSize != NULL)
181  *pSize = ((struct SecrSifDiskBootHeaderParams *)RpcBuffer)->size;
182  result = ((struct SecrSifDiskBootHeaderParams *)RpcBuffer)->result;
183  }
184 
185  return result;
186 }
187 
188 int SecrDiskBootBlock(void *src, void *dst, unsigned int size)
189 {
190  int result;
191 
192  memcpy(((struct SecrSifDiskBootBlockParams *)RpcBuffer)->source, src, size);
193  ((struct SecrSifDiskBootBlockParams *)RpcBuffer)->size = size;
194 
195  if (sceSifCallRpc(&SifRpcClient07, 1, 0, RpcBuffer, sizeof(RpcBuffer), RpcBuffer, sizeof(RpcBuffer), NULL, NULL) < 0) {
196  _printf("sceSecrDiskBootBlock: rpc error\n");
197  result = 0;
198  } else {
199  result = ((struct SecrSifDiskBootBlockParams *)RpcBuffer)->result;
200  memcpy(dst, ((struct SecrSifDiskBootBlockParams *)RpcBuffer)->destination, size);
201  }
202 
203  return result;
204 }
205 
206 static unsigned short int GetHeaderLength(const void *buffer)
207 {
208  return ((const SecrKELFHeader_t *)buffer)->KELF_header_size;
209 }
210 
211 static void store_kbit(void *buffer, const void *kbit)
212 {
213  const SecrKELFHeader_t *header = buffer;
214  int offset = 0x20, kbit_offset;
215 
216  if (header->BIT_count > 0)
217  offset += header->BIT_count * sizeof(SecrBitBlockData_t);
218  if (((header->flags) & 1) != 0)
219  offset += ((unsigned char *)buffer)[offset] + 1;
220  if (((header->flags) & 0xF000) == 0)
221  offset += 8;
222 
223  kbit_offset = (unsigned int)buffer + offset;
224  memcpy((void *)kbit_offset, kbit, 16);
225  _printf("kbit_offset: %d\n", kbit_offset);
226 }
227 
228 static void store_kc(void *buffer, const void *kc)
229 {
230  const SecrKELFHeader_t *header = buffer;
231  int offset = 0x20, kc_offset;
232 
233  if (header->BIT_count > 0)
234  offset += header->BIT_count * sizeof(SecrBitBlockData_t);
235  if (((header->flags) & 1) != 0)
236  offset += ((unsigned char *)buffer)[offset] + 1;
237  if (((header->flags) & 0xF000) == 0)
238  offset += 8;
239 
240  kc_offset = (unsigned int)buffer + offset + 0x10; // Goes after Kbit.
241  memcpy((void *)kc_offset, kc, 16);
242  _printf("kc_offset: %d\n", kc_offset);
243 }
244 
245 static int Uses_ICVPS2(const void *buffer)
246 {
247  return (((const SecrKELFHeader_t *)buffer)->flags >> 1 & 1);
248 }
249 
250 static void store_icvps2(void *buffer, const void *icvps2)
251 {
252  unsigned int pICVPS2;
253 
254  pICVPS2 = (unsigned int)buffer + ((SecrKELFHeader_t *)buffer)->KELF_header_size - 8;
255  memcpy((void *)pICVPS2, icvps2, 8);
256  _printf("icvps2_offset %d\n", pICVPS2);
257 }
258 
259 static unsigned int get_BitTableOffset(const void *buffer)
260 {
261  const SecrKELFHeader_t *header = buffer;
262  int offset = sizeof(SecrKELFHeader_t);
263 
264  if (header->BIT_count > 0)
265  offset += header->BIT_count * sizeof(SecrBitBlockData_t); // They used a loop for this. D:
266  if ((header->flags & 1) != 0)
267  offset += ((const unsigned char *)buffer)[offset] + 1;
268  if ((header->flags & 0xF000) == 0)
269  offset += 8;
270  return (offset + 0x20); // Goes after Kbit and Kc.
271 }
272 
273 void *SecrDownloadFile(int port, int slot, void *buffer)
274 {
275  SecrBitTable_t BitTableData;
276  void *result;
277 
278  _printf("SecrDownloadFile start\n");
279  if (SecrDownloadHeader(port, slot, buffer, &BitTableData, NULL) != 0) {
280  unsigned char kbit[16], kcontent[16];
281 
282  if (BitTableData.header.block_count > 0) {
283  unsigned int offset, i;
284 
285  offset = BitTableData.header.headersize;
286  for (i = 0; i < BitTableData.header.block_count; i++) {
287  if (BitTableData.blocks[i].flags & 2) {
288  if (!SecrDownloadBlock((void *)((unsigned int)buffer + offset), BitTableData.blocks[i].size)) {
289  _printf("SecrDownloadFile: failed\n");
290  return NULL;
291  }
292  }
293  offset += BitTableData.blocks[i].size;
294  }
295  }
296 
297  if (SecrDownloadGetKbit(port, slot, kbit) == 0) {
298  _printf("SecrDownloadFile: Cannot get kbit\n");
299  return NULL;
300  }
301  if (SecrDownloadGetKc(port, slot, kcontent) == 0) {
302  _printf("SecrDownloadFile: Cannot get kc\n");
303  return NULL;
304  }
305 
306  store_kbit(buffer, kbit);
307  store_kc(buffer, kcontent);
308 
309  if (Uses_ICVPS2(buffer) == 1) {
310  unsigned char icvps2[8];
311 
312  if (SecrDownloadGetICVPS2(icvps2) == 0) {
313  _printf("SecrDownloadFile: Cannot get icvps2\n");
314  return NULL;
315  }
316 
317  store_icvps2(buffer, icvps2);
318  }
319 
320  result = buffer;
321  } else {
322  _printf("SecrDownloadFile: Cannot encrypt header\n");
323  return NULL;
324  }
325 
326  _printf("SecrDownloadFile complete\n");
327 
328  return result;
329 }
330 
331 void *SecrDiskBootFile(void *buffer)
332 {
333  void *result;
334  SecrBitTable_t *BitTableData;
335 
336  BitTableData = (SecrBitTable_t *)((unsigned int)buffer + get_BitTableOffset(buffer));
337  if (SecrDiskBootHeader(buffer, BitTableData, NULL)) {
338  if (BitTableData->header.block_count > 0) {
339  unsigned int offset, i;
340 
341  offset = BitTableData->header.headersize;
342  for (i = 0; i < BitTableData->header.block_count; i++) {
343  if (BitTableData->blocks[i].flags & 3) {
344  if (!SecrDiskBootBlock((void *)((unsigned int)buffer + offset), (void *)((unsigned int)buffer + offset), BitTableData->blocks[i].size)) {
345  _printf("SecrDiskBootFile: failed\n");
346  return NULL;
347  }
348  }
349  offset += BitTableData->blocks[i].size;
350  }
351  }
352 
353  result = (void *)((unsigned int)buffer + GetHeaderLength(buffer));
354  } else {
355  _printf("sceSecrDiskBootFile: Cannot decrypt header\n");
356  result = NULL;
357  }
358 
359  return result;
360 }
kernel.h
SecrBitBlockData_t
struct SecrBitBlockData SecrBitBlockData_t
SecrBitTableHeader::block_count
u8 block_count
Definition: libsecr-common.h:36
SecrKELFHeader_t
struct KELF_Header SecrKELFHeader_t
SecrSifDownloadHeaderParams
Definition: secrsif.h:1
SecrSifDownloadGetKbitParams
Definition: secrsif.h:17
SecrSifDiskBootBlockParams
Definition: secrsif.h:45
iopcontrol.h
SecrBitBlockData::flags
u32 flags
Definition: libsecr-common.h:27
SecrBitTableHeader::headersize
u32 headersize
Definition: libsecr-common.h:34
KELF_Header::BIT_count
u16 BIT_count
Definition: libsecr-common.h:62
SecrBitTable
Definition: libsecr-common.h:43
HasIopRebootedSinceLastCall
static int HasIopRebootedSinceLastCall(void)
Definition: iopcontrol.h:47
SecrSifDownloadGetKcParams
Definition: secrsif.h:24
stdio.h
SecrBitBlockData::size
u32 size
Definition: libsecr-common.h:25
SecrBitTable::blocks
SecrBitBlockData_t blocks[63]
Definition: libsecr-common.h:47
t_SifRpcClientData
Definition: sifrpc-common.h:134
SecrSifDiskBootHeaderParams
Definition: secrsif.h:37
KELF_Header
Definition: libsecr-common.h:51
SecrSifDownloadGetIcvps2Params
Definition: secrsif.h:31
KELF_Header::flags
u16 flags
Definition: libsecr-common.h:60
SecrSifDownloadBlockParams
Definition: secrsif.h:10