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