LibXenon
Bare-metal Xbox 360 homebrew library
Loading...
Searching...
No Matches
xb360.c
Go to the documentation of this file.
1/*
2 * xb360.c
3 *
4 * Created on: Sep 4, 2008
5 */
6
7#include <string.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <sys/stat.h>
11#include <pci/io.h>
12#include <time/time.h>
16#include <xenon_smc/xenon_smc.h>
17#include <crypt/hmac_sha1.h>
18#include <crypt/rc4.h>
19
20#include "xb360.h"
21
23
24extern struct sfc sfc;
25
26static const kventry kvlookup[] =
27 {
28 {XEKEY_MANUFACTURING_MODE, 0x18, 0x01},
29 {XEKEY_ALTERNATE_KEY_VAULT, 0x19, 0x01},
30 {XEKEY_RESERVED_BYTE2, 0x1A, 0x01},
31 {XEKEY_RESERVED_BYTE3, 0x1B, 0x01},
32 {XEKEY_RESERVED_WORD1, 0x1C, 0x02},
33 {XEKEY_RESERVED_WORD2, 0x1E, 0x02},
35 {XEKEY_RESERVED_DWORD2, 0x24, 0x04},
36 {XEKEY_RESERVED_DWORD3, 0x28, 0x04},
37 {XEKEY_RESERVED_DWORD4, 0x2c, 0x04},
38 {XEKEY_RESTRICTED_PRIVILEDGES, 0x30, 0x08},
39 {XEKEY_RESERVED_QWORD2, 0x38, 0x08},
40 {XEKEY_RESERVED_QWORD3, 0x40, 0x08},
41 {XEKEY_RESERVED_QWORD4, 0x48, 0x08},
42 {XEKEY_RESERVED_KEY1, 0x50, 0x10},
43 {XEKEY_RESERVED_KEY2, 0x60, 0x10},
44 {XEKEY_RESERVED_KEY3, 0x70, 0x10},
45 {XEKEY_RESERVED_KEY4, 0x80, 0x10},
46 {XEKEY_RESERVED_RANDOM_KEY1, 0x90, 0x10},
47 {XEKEY_RESERVED_RANDOM_KEY2, 0xA0, 0x10},
48 {XEKEY_CONSOLE_SERIAL_NUMBER, 0xB0, 0x0C},
49 {XEKEY_MOBO_SERIAL_NUMBER, 0xBC, 0x0C},
50 {XEKEY_GAME_REGION, 0xC8, 0x02},
52 {XEKEY_KEY_OBFUSCATION_KEY, 0xE0, 0x10},
54 {XEKEY_DVD_KEY, 0x100, 0x10},
55 {XEKEY_PRIMARY_ACTIVATION_KEY, 0x110, 0x18},
56 {XEKEY_SECONDARY_ACTIVATION_KEY, 0x128, 0x10},
57 {XEKEY_GLOBAL_DEVICE_2DES_KEY1, 0x138, 0x10},
58 {XEKEY_GLOBAL_DEVICE_2DES_KEY2, 0x148, 0x10},
65 {XEKEY_MEMORY_UNIT_MS_2DES_KEY1, 0x1B8, 0x10},
66 {XEKEY_MEMORY_UNIT_MS_2DES_KEY2, 0x1C8, 0x10},
75 {XEKEY_MEMORY_UNIT_3P_2DES_KEY1, 0x258, 0x10},
76 {XEKEY_MEMORY_UNIT_3P_2DES_KEY2, 0x268, 0x10},
79 {XEKEY_CONSOLE_PRIVATE_KEY, 0x298, 0x1D0},
80 {XEKEY_XEIKA_PRIVATE_KEY, 0x468, 0x390},
81 {XEKEY_CARDEA_PRIVATE_KEY, 0x7F8, 0x1D0},
82 {XEKEY_CONSOLE_CERTIFICATE, 0x9C8, 0x1A8},
83 {XEKEY_XEIKA_CERTIFICATE, 0xB70, 0x1388},
84 {XEKEY_CARDEA_CERTIFICATE, 0x1EF8, 0x2108}
85 };
86
87void print_key(char *name, unsigned char *data)
88{
89 int i=0;
90 printf("%s: ", name);
91 for(i=0; i<16; i++)
92 printf("%02X",data[i]);
93 printf("\n");
94}
95
96void print_cserial(char *name, unsigned char *data)
97{
98 int i = 0;
99 printf("%s: ", name);
100 for (i = 0; i < 12; i++)
101 printf("%c", data[i]);
102 printf("\n");
103}
104
105int cpu_get_key(unsigned char *data)
106{
107 *(unsigned long long*)&data[0] = xenon_secotp_read_line(3) | xenon_secotp_read_line(4);
108 *(unsigned long long*)&data[8] = xenon_secotp_read_line(5) | xenon_secotp_read_line(6);
109 return 0;
110}
111
112int get_virtual_cpukey(unsigned char *data)
113{
114 unsigned char buffer[VFUSES_SIZE];
115
116 uint32_t patchSlotOffset = 0;
117 uint32_t patchSlotSize = 0;
118 uint16_t patchSlotCount = 0;
119
120 const unsigned char fuseline0[0x8] = { 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
121
122 // JTAG virtual fuses must be checked manually, since they're not stored
123 // at the beginning of either of the patch slots like Glitch/DevGL images
125 {
126 // Error reading NAND data
127 return 2;
128 }
129
130 // Data was read from NAND, verify that it looks like a virtual fuse set
131 // by comparing it with what is expected for fuseline 0.
132 if( 0 == memcmp(buffer, fuseline0, sizeof(fuseline0)) )
133 {
134 memcpy(data,&buffer[0x20],0x10);
135 return 0;
136 }
137
138 // If virtual fuses were not found at the JTAG offset, check the beginning of each patch slot.
139 // Patch slot offset, count, and size are stored at the beginning of NAND
140
141 // Patch slot offset = DWORD at 0x64
142 if (xenon_get_logical_nand_data(&patchSlotOffset, 0x64, sizeof(patchSlotOffset)) == -1)
143 {
144 return 2;
145 }
146
147 // Patch slot count = WORD at 0x68
148 if (xenon_get_logical_nand_data(&patchSlotCount, 0x68, sizeof(patchSlotCount)) == -1)
149 {
150 return 2;
151 }
152
153 // Patch slot size = DWORD at 0x70
154 if (xenon_get_logical_nand_data(&patchSlotSize, 0x70, sizeof(patchSlotSize)) == -1)
155 {
156 return 2;
157 }
158
159 // XeBuild has a bug where the patch slot size is set to zero for
160 // Falcon/Zephyr/Xenon DevGL and Glitch2m images. In this case, use
161 // the expected patch slot size of 0x10000 bytes.
162 if( 0 == patchSlotSize )
163 {
164 patchSlotSize = 0x10000;
165 }
166
167 // Check the beginning of each patch slot for a virtual fuse set
168 for(int i = 0; i < patchSlotCount; i++)
169 {
170 uint32_t patchSlotAddress = patchSlotOffset + (i * patchSlotSize);
171
172 // Read the virtual fuse set from NAND
173 if (xenon_get_logical_nand_data(&buffer, patchSlotAddress, VFUSES_SIZE) == -1)
174 {
175 return 2;
176 }
177
178 // Data was read from NAND, verify that it looks like a virtual fuse set
179 // by comparing it with what is expected for fuseline 0. If it doesn't
180 // match, the next patch slot will be checked.
181 if( 0 == memcmp(buffer, fuseline0, sizeof(fuseline0)) )
182 {
183 memcpy(data,&buffer[0x20],0x10);
184 return 0;
185 }
186 }
187
188 // No virtual fuses found
189 return 1;
190}
191
192
193int kv_get_key(unsigned char keyid, unsigned char *keybuf, int *keybuflen, unsigned char *keyvault)
194{
195 if (keyid > 0x38)
196 return 1;
197
198 if (*keybuflen != kvlookup[keyid].length)
199 {
200 *keybuflen = kvlookup[keyid].length;
201 return 2;
202 }
203 memcpy(keybuf, keyvault + kvlookup[keyid].offset, kvlookup[keyid].length);
204
205 return 0;
206}
207
208
209int kv_read(unsigned char *data, int virtualcpukey)
210{
212 return -1;
213
214 unsigned char cpu_key[0x10];
215 if (virtualcpukey)
216 get_virtual_cpukey(cpu_key);
217 else
218 cpu_get_key(cpu_key);
219 //print_key("kv_read: cpu key", cpu_key);
220
221 unsigned char hmac_key[0x10];
222 memcpy(hmac_key, data, 0x10);
223 //print_key("kv_read: hmac key", hmac_key);
224
225 unsigned char rc4_key[0x10];
226 memset(rc4_key, 0, 0x10);
227
228 HMAC_SHA1(cpu_key, hmac_key, rc4_key, 0x10);
229 //print_key("kv_read: rc4 key", rc4_key);
230
231 unsigned char rc4_state[0x100];
232 memset(rc4_state, 0, 0x100);
233
234 rc4_init(rc4_state, rc4_key ,0x10);
235 rc4_crypt(rc4_state, (unsigned char*) &data[0x10], KV_FLASH_SIZE - 0x10);
236
237 //Now then do a little check to make sure it is somewhat correct
238 //We check the hmac_sha1 of the data and compare that to
239 //the hmac_sha1 key in the header of the keyvault
240 //basically the reverse of what we did to generate the key for rc4
241 unsigned char data2[KV_FLASH_SIZE];
242 unsigned char out[20];
243 unsigned char tmp[] = {0x07, 0x12};
244 HMAC_SHA1_CTX ctx;
245
246 //the hmac_sha1 seems destructive
247 //so we make a copy of the data
248 memcpy(data2, data, KV_FLASH_SIZE);
249
250 HMAC_SHA1_Init(&ctx);
251 HMAC_SHA1_UpdateKey(&ctx, (unsigned char *) cpu_key, 0x10);
252 HMAC_SHA1_EndKey(&ctx);
253
255
256 HMAC_SHA1_UpdateMessage(&ctx, (unsigned char*) &data2[0x10], KV_FLASH_SIZE - 0x10);
257 HMAC_SHA1_UpdateMessage(&ctx, (unsigned char*) &tmp[0x00], 0x02); //Special appendage
258
259 HMAC_SHA1_EndMessage(out, &ctx);
260 HMAC_SHA1_Done(&ctx);
261
262 int index = 0;
263 while (index < 0x10)
264 {
265 if (data[index] != out[index])
266 {
267 // Hmm something is wrong, hmac is not matching
268 //printf(" ! kv_read: kv hash check failed\n");
269 return 2;
270 }
271 index += 1;
272 }
273
274 return 0;
275}
276
278{
279 unsigned int kvOffset = xenon_get_kv_offset();
280 unsigned int kvSize = xenon_get_kv_size();
281
282 // Physical KV offset = page number * physical page size + offset in page
283 kvOffset = ((kvOffset / sfc.page_sz) * sfc.page_sz_phys) + (kvOffset % sfc.page_sz);
284
285 // Physical KV size = page count * physical page size (KV is a multiple of page size)
286 kvSize = (kvSize / sfc.page_sz) * sfc.page_sz_phys;
287
288 printf(" ! the hash check failed probably as a result of decryption failure\n");
289 printf(" ! make sure that the CORRECT key vault for this console is in flash\n");
290 printf(" ! the key vault should be at offset 0x%x for a length of 0x%x\n", kvOffset, kvSize);
291 printf(" ! in the 'raw' flash binary from THIS console\n");
292
293 return;
294}
295
296int kv_get_dvd_key(unsigned char *dvd_key)
297{
298 if (KV_FLASH_SIZE == 0)
299 return -1; //It's bad data!
300 unsigned char buffer[KV_FLASH_SIZE], cpukeyTmp[0x10];
301 int result = 0;
302 int keylen = 0x10;
303
304 result = kv_read(buffer, 0);
305 if (result == 2 && get_virtual_cpukey(cpukeyTmp) == 0){
306 result = kv_read(buffer, 1);
307 }
308
309 if (result != 0){
310 printf(" ! kv_get_dvd_key Failure: kv_read\n");
311 // Hash failure
312 if (result == 2){
314 }
315 return 1;
316 }
317
318 result = kv_get_key(XEKEY_DVD_KEY, dvd_key, &keylen, buffer);
319 if (result != 0){
320 printf(" ! kv_get_dvd_key Failure: kv_get_key %d\n", result);
321 return result;
322 }
323
324 return 0;
325}
326
327int kv_get_cserial(unsigned char *serial)
328{
329 if (KV_FLASH_SIZE == 0)
330 return -1; //It's bad data!
331 unsigned char buffer[KV_FLASH_SIZE], cpukeyTmp[0x10];
332 int result = 0;
333 int serialLen = 0xC;
334
335 result = kv_read(buffer, 0);
336 if (result == 2 && get_virtual_cpukey(cpukeyTmp) == 0){
337 result = kv_read(buffer, 1);
338 }
339
340 if (result != 0){
341 printf(" ! kv_get_cserial Failure: kv_read\n");
342 // Hash failure
343 if (result == 2){
345 }
346 return 1;
347 }
348
349 result = kv_get_key(XEKEY_CONSOLE_SERIAL_NUMBER, serial, &serialLen, buffer);
350 if (result != 0){
351 printf(" ! kv_get_cserial Failure: kv_get_key %d\n", result);
352 return result;
353 }
354
355 return 0;
356}
357
359{
360 unsigned char key[0x10];
361 unsigned char cserial[0xC];
362
363 printf("\n");
364
365 memset(key, '\0', sizeof(key));
366
367 if (cpu_get_key(key)==0)
368 {
369 print_key(" * CPU key", key);
370 }
371
373 {
374 printf(" ! Unable to read Keyvault data from NAND\n");
375 printf(" ! xenon_logical_nand_data_ok error\n");
376 }
377 else if(KV_FLASH_OFFSET == 0 || KV_FLASH_SIZE == 0)
378 {
379 printf(" ! Unable to read Keyvault data from NAND\n");
380 printf(" ! Keyvault size or offset is zero\n");
381 }
382 else
383 {
384 memset(key, '\0',sizeof(key));
385 if (get_virtual_cpukey(key)==0)
386 print_key(" * Virtual CPU key", key);
387
388 memset(key, '\0', sizeof(key));
389 if (kv_get_dvd_key(key)==0)
390 print_key(" * DVD key", key);
391
392 memset(cserial, '\0', sizeof(cserial));
393 if (kv_get_cserial(cserial)==0)
394 print_cserial(" * Serial", cserial);
395 }
396
397 printf("\n");
398}
399
400//This version crashes... dunno why... but... old one works perfectly fine so, why change it?!
401
402//int updateXeLL(void * addr, unsigned len)
403//{
404// int i, j, k, startblock, current, offsetinblock, blockcnt;
405// unsigned char *user, *spare;
406//
407// if (sfc.initialized != SFCX_INITIALIZED){
408// printf(" ! sfcx is not initialized! Unable to update XeLL in NAND!\n");
409// return -1;
410// }
411//
412// printf("\n * found XeLL update. press power NOW if you don't want to update.\n");
413// delay(15);
414//
415// for (k = 0; k < XELL_OFFSET_COUNT; k++)
416// {
417// current = xelloffsets[k];
418// offsetinblock = current % sfc.block_sz;
419// startblock = current/sfc.block_sz;
420// blockcnt = offsetinblock ? (XELL_SIZE/sfc.block_sz)+1 : (XELL_SIZE/sfc.block_sz);
421//
422//
423// spare = (unsigned char*)malloc(blockcnt*sfc.pages_in_block*sfc.meta_sz);
424// if(!spare){
425// printf(" ! Error while memallocating filebuffer (spare)\n");
426// return -1;
427// }
428// user = (unsigned char*)malloc(blockcnt*sfc.block_sz);
429// if(!user){
430// printf(" ! Error while memallocating filebuffer (user)\n");
431// return -1;
432// }
433// j = 0;
434// unsigned char pagebuf[MAX_PAGE_SZ];
435//
436// for (i = (startblock*sfc.pages_in_block); i< (startblock+blockcnt)*sfc.pages_in_block; i++)
437// {
438// sfcx_read_page(pagebuf, (i*sfc.page_sz), 1);
439// //Split rawpage into user & spare
440// memcpy(&user[j*sfc.page_sz],pagebuf,sfc.page_sz);
441// memcpy(&spare[j*sfc.meta_sz],&pagebuf[sfc.page_sz],sfc.meta_sz);
442// j++;
443// }
444//
445// if (memcmp(&user[offsetinblock+(XELL_FOOTER_OFFSET)],XELL_FOOTER,XELL_FOOTER_LENGTH) == 0){
446// printf(" * XeLL Binary in NAND found @ 0x%08X\n", (startblock*sfc.block_sz)+offsetinblock);
447//
448// memcpy(&user[offsetinblock], addr,len); //Copy over updxell.bin
449// printf(" * Writing to NAND!\n");
450// j = 0;
451// for (i = startblock*sfc.pages_in_block; i < (startblock+blockcnt)*sfc.pages_in_block; i ++)
452// {
453// if (!(i%sfc.pages_in_block))
454// sfcx_erase_block(i*sfc.page_sz);
455//
456// /* Copy user & spare data together in a single rawpage */
457// memcpy(pagebuf,&user[j*sfc.page_sz],sfc.page_sz);
458// memcpy(&pagebuf[sfc.page_sz],&spare[j*sfc.meta_sz],sfc.meta_sz);
459// j++;
460//
461// if (!(sfcx_is_pageerased(pagebuf))) // We dont need to write to erased pages
462// {
463// memset(&pagebuf[sfc.page_sz+0x0C],0x0, 4); //zero only EDC bytes
464// sfcx_calcecc((unsigned int *)pagebuf); //recalc EDC bytes
465// sfcx_write_page(pagebuf, i*sfc.page_sz);
466// }
467// }
468// printf(" * XeLL flashed! Reboot the xbox to enjoy the new build\n");
469// for(;;);
470//
471// }
472// }
473// printf(" ! Couldn't locate XeLL binary in NAND. Aborting!\n");
474// return -1; // if this point is reached, updating xell failed
475//}
476
477int updateXeLL(char *path)
478{
479 FILE *f;
480 int i, j, k, status, startblock, current, offsetinblock, blockcnt, filelength;
481 unsigned char *updxell, *user, *spare;
482 struct stat s;
483
484 memset(&s, 0, sizeof(struct stat));
485 stat(path, &s);
486 long size = s.st_size;
487 if (size <= 0)
488 return -1; //Invalid Filesize
489
490 /* Check if updxell.bin is present */
491 f = fopen(path, "rb");
492 if (!f){
493 return -1; //Can't find/open updxell.bin
494 }
495
497 fclose(f);
498 printf(" ! sfcx is not initialized! Unable to update XeLL in NAND!\n");
499 return -1;
500 }
501
502 /* Check filesize of updxell.bin, only accept full 256kb binaries */
503 fseek(f, 0, SEEK_END);
504 filelength=ftell(f);
505 fseek(f, 0, SEEK_SET);
506 if (filelength != XELL_SIZE){
507 fclose(f);
508 printf(" ! %s does not have the correct size of 256kb. Aborting update!\n", path);
509 return -1;
510 }
511
512 printf("\n * found XeLL update. press power NOW if you don't want to update.\n");
513 delay(15);
514
515 for (k = 0; k < XELL_OFFSET_COUNT; k++)
516 {
517 current = xelloffsets[k];
518 offsetinblock = current % sfc.block_sz;
519 startblock = current/sfc.block_sz;
520 blockcnt = offsetinblock ? (XELL_SIZE/sfc.block_sz)+1 : (XELL_SIZE/sfc.block_sz);
521
522
523 spare = (unsigned char*)malloc(blockcnt*sfc.pages_in_block*sfc.meta_sz);
524 if(!spare){
525 printf(" ! Error while memallocating filebuffer (spare)\n");
526 return -1;
527 }
528 user = (unsigned char*)malloc(blockcnt*sfc.block_sz);
529 if(!user){
530 printf(" ! Error while memallocating filebuffer (user)\n");
531 return -1;
532 }
533 j = 0;
534 unsigned char pagebuf[MAX_PAGE_SZ];
535
536 for (i = (startblock*sfc.pages_in_block); i< (startblock+blockcnt)*sfc.pages_in_block; i++)
537 {
539 //Split rawpage into user & spare
540 memcpy(&user[j*sfc.page_sz],pagebuf,sfc.page_sz);
541 memcpy(&spare[j*sfc.meta_sz],&pagebuf[sfc.page_sz],sfc.meta_sz);
542 j++;
543 }
544
545 if (memcmp(&user[offsetinblock+(XELL_FOOTER_OFFSET)],XELL_FOOTER,XELL_FOOTER_LENGTH) == 0){
546 printf(" * XeLL Binary in NAND found @ 0x%08X\n", (startblock*sfc.block_sz)+offsetinblock);
547
548 updxell = (unsigned char*)malloc(XELL_SIZE);
549 if(!updxell){
550 printf(" ! Error while memallocating filebuffer (updxell)\n");
551 return -1;
552 }
553
554 status = fread(updxell,1,XELL_SIZE,f);
555 if (status != XELL_SIZE){
556 fclose(f);
557 printf(" ! Error reading file from %s\n", path);
558 return -1;
559 }
560
561 if (memcmp(&updxell[XELL_FOOTER_OFFSET],XELL_FOOTER, XELL_FOOTER_LENGTH)){
562 printf(" ! XeLL does not seem to have matching footer, Aborting update!\n");
563 return -1;
564 }
565
566 fclose(f);
567 memcpy(&user[offsetinblock], updxell,XELL_SIZE); //Copy over updxell.bin
568 printf(" * Writing to NAND!\n");
569 j = 0;
570 for (i = startblock*sfc.pages_in_block; i < (startblock+blockcnt)*sfc.pages_in_block; i ++)
571 {
572 if (!(i%sfc.pages_in_block))
574
575 /* Copy user & spare data together in a single rawpage */
576 memcpy(pagebuf,&user[j*sfc.page_sz],sfc.page_sz);
577 memcpy(&pagebuf[sfc.page_sz],&spare[j*sfc.meta_sz],sfc.meta_sz);
578 j++;
579
580 if (!(sfcx_is_pageerased(pagebuf))) // We dont need to write to erased pages
581 {
582 memset(&pagebuf[sfc.page_sz+0x0C],0x0, 4); //zero only EDC bytes
583 sfcx_calcecc((unsigned int *)pagebuf); //recalc EDC bytes
585 }
586 }
587 printf(" * XeLL flashed! Reboot the xbox to enjoy the new build\n");
588 for(;;);
589
590 }
591 }
592 printf(" ! Couldn't locate XeLL binary in NAND. Aborting!\n");
593 return -1;
594}
595
596unsigned int xenon_get_DVE()
597{
598 unsigned int DVEversion, tmp;
599 xenon_smc_ana_read(0xfe, &DVEversion);
600 tmp = DVEversion;
601 tmp = (tmp & ~0xF0) | ((DVEversion >> 12) & 0xF0);
602 return (tmp & 0xFF);
603}
604
606{
607 return ((read32(0xd0000008) << 24) >> 24);
608}
609
610unsigned int xenon_get_CPU_PVR()
611{
612 unsigned int PVR;
613 asm volatile("mfpvr %0" : "=r" (PVR));
614 return PVR;
615}
616
617unsigned int xenon_get_XenosID()
618{
619 return ((read32(0xd0010000) >> 16) & 0xFFFF);
620}
621
623{
624 unsigned int PVR, PCIBridgeRevisionID, DVEversion;
625
626 PCIBridgeRevisionID = xenon_get_PCIBridgeRevisionID();
627 DVEversion = xenon_get_DVE();
628 PVR = xenon_get_CPU_PVR();
629
630 if(PVR <= 0x710300) // DD3 or older CPU, must be a Xenon or Zephyr
631 {
632 if(DVEversion >= 0x11) // We've got HANA, this must be a zephyr
633 {
634 return REV_ZEPHYR;
635 }
636 else
637 {
638 return REV_XENON;
639 }
640 }
641 else if(PVR <= 0x710500) // Loki CPU, must be a Falcon or Jasper
642 {
643 if(PCIBridgeRevisionID >= 0x60)
644 {
645 return REV_JASPER;
646 }
647 else
648 {
649 return REV_FALCON;
650 }
651 }
652 else if(PVR <= 0x710800) // Vejle CPU, must be Trinity or Corona
653 {
654 if (DVEversion >= 0x20)
655 {
656 if (PCIBridgeRevisionID >= 0x70 && sfcx_readreg(SFCX_PHISON) != 0)
657 return REV_CORONA_PHISON;
658 return REV_CORONA;
659 }
660 else
661 return REV_TRINITY;
662 }
663 else if(PVR <= 0x710A00) // Oban CPU, must be Winchester
664 {
665 if (PCIBridgeRevisionID >= 0x70 && sfcx_readreg(SFCX_PHISON) != 0)
666 return REV_WINCHESTER_MMC;
667 return REV_WINCHESTER;
668 }
669
670 return REV_UNKNOWN;
671}
672
674{
675 uint16_t tmp;
676 memcpy(&tmp, (const void*)(0x80000200C8000000ULL), 2);
677 if (tmp != 0xFF4F)
678 return -1;
679 return 0;
680}
681
682int xenon_get_logical_nand_data(void* buf, unsigned int offset, unsigned int len)
683{
685 memcpy(buf, (const void*)(0x80000200C8000000ULL + offset), len);
686 else
687 return -1;
688 return 0;
689}
690
691unsigned int xenon_get_kv_size()
692{
693 unsigned int ret;
694 if (xenon_get_logical_nand_data(&ret, 0x60, 4) == 0)
695 return ret;
696 return 0;
697}
698
700{
701 unsigned int ret;
702 if (xenon_get_logical_nand_data(&ret, 0x6C, 4) == 0)
703 return ret;
704 return 0;
705}
706
707unsigned int xenon_get_ram_size()
708{
709 // 0xE1040000 is the host bridge register where HWINIT stores a little endian uint32
710 // representing the amount of memory (in bytes) installed on the system. CB_B looks
711 // here to determine whether or not to throw panic 0xAF (UNSUPPORTED_RAM_SIZE)
712 return __builtin_bswap32(*(unsigned int *)0xE1040000);
713}
uint16_t length
Definition: ata.h:4
u32 status
Definition: ehci_defs.h:15
void HMAC_SHA1_EndMessage(unsigned char *out, HMAC_SHA1_CTX *ctx)
Definition: hmac_sha1.c:170
void HMAC_SHA1(void *secret, void *data, void *res, int len)
Definition: hmac_sha1.c:190
void HMAC_SHA1_UpdateMessage(HMAC_SHA1_CTX *ctx, unsigned char *data, unsigned int datalen)
Definition: hmac_sha1.c:166
void HMAC_SHA1_Done(HMAC_SHA1_CTX *ctx)
Definition: hmac_sha1.c:181
void HMAC_SHA1_Init(HMAC_SHA1_CTX *ctx)
Definition: hmac_sha1.c:71
void HMAC_SHA1_StartMessage(HMAC_SHA1_CTX *ctx)
Definition: hmac_sha1.c:161
void HMAC_SHA1_UpdateKey(HMAC_SHA1_CTX *ctx, unsigned char *key, unsigned int keylen)
Definition: hmac_sha1.c:79
void HMAC_SHA1_EndKey(HMAC_SHA1_CTX *ctx)
Definition: hmac_sha1.c:133
u32 size
Definition: iso9660.c:537
u32 uint32_t
Definition: libfdt_env.h:11
u16 uint16_t
Definition: libfdt_env.h:10
int stat(const char *file, struct stat *st)
Definition: newlib.c:643
void rc4_init(unsigned char *state, unsigned char *key, int len)
Definition: rc4.c:5
void rc4_crypt(unsigned char *state, unsigned char *data, int len)
Definition: rc4.c:22
Definition: xb360.h:104
int length
Definition: xb360.h:107
Definition: xenon_sfcx.h:86
int page_sz_phys
Definition: xenon_sfcx.h:92
int page_sz
Definition: xenon_sfcx.h:90
int meta_sz
Definition: xenon_sfcx.h:91
int block_sz
Definition: xenon_sfcx.h:95
int initialized
Definition: xenon_sfcx.h:87
int pages_in_block
Definition: xenon_sfcx.h:94
void delay(int u)
Definition: time.c:22
int xenon_get_logical_nand_data(void *buf, unsigned int offset, unsigned int len)
Definition: xb360.c:682
unsigned int xenon_get_CPU_PVR()
Definition: xb360.c:610
int kv_get_cserial(unsigned char *serial)
Definition: xb360.c:327
void kv_print_hash_failure()
Definition: xb360.c:277
void print_key(char *name, unsigned char *data)
Definition: xb360.c:87
int get_virtual_cpukey(unsigned char *data)
Definition: xb360.c:112
int updateXeLL(char *path)
Definition: xb360.c:477
unsigned int xenon_get_PCIBridgeRevisionID()
Definition: xb360.c:605
unsigned int xenon_get_kv_offset()
Definition: xb360.c:699
unsigned int xenon_get_XenosID()
Definition: xb360.c:617
int kv_read(unsigned char *data, int virtualcpukey)
Definition: xb360.c:209
void print_cpu_dvd_keys(void)
Definition: xb360.c:358
unsigned int xenon_get_ram_size()
Definition: xb360.c:707
struct XCONFIG_SECURED_SETTINGS secured_settings
Definition: xenon_config.c:17
int kv_get_key(unsigned char keyid, unsigned char *keybuf, int *keybuflen, unsigned char *keyvault)
Definition: xb360.c:193
unsigned int xenon_get_DVE()
Definition: xb360.c:596
unsigned int xenon_get_kv_size()
Definition: xb360.c:691
int xenon_logical_nand_data_ok()
Definition: xb360.c:673
void print_cserial(char *name, unsigned char *data)
Definition: xb360.c:96
int xenon_get_console_type()
Definition: xb360.c:622
int cpu_get_key(unsigned char *data)
Definition: xb360.c:105
int kv_get_dvd_key(unsigned char *dvd_key)
Definition: xb360.c:296
#define XEKEY_RESERVED_WORD2
Definition: xb360.h:15
#define XEKEY_RESERVED_QWORD2
Definition: xb360.h:21
#define XELL_SIZE
Definition: xb360.h:78
#define XEKEY_RESERVED_KEY4
Definition: xb360.h:27
#define KV_FLASH_SIZE
Definition: xb360.h:71
#define XEKEY_WIRELESS_CONTROLLER_3P_2DES_KEY1
Definition: xb360.h:51
#define XEKEY_WIRED_CONTROLLER_3P_2DES_KEY2
Definition: xb360.h:56
#define KV_FLASH_OFFSET
Definition: xb360.h:72
#define XEKEY_KEY_OBFUSCATION_KEY
Definition: xb360.h:34
#define XEKEY_RESERVED_BYTE3
Definition: xb360.h:13
#define REV_XENON
Definition: xb360.h:93
#define XEKEY_GLOBAL_DEVICE_2DES_KEY1
Definition: xb360.h:39
#define XEKEY_ROAMABLE_OBFUSCATION_KEY
Definition: xb360.h:35
#define REV_CORONA
Definition: xb360.h:98
#define VFUSES_SIZE
Definition: xb360.h:75
#define XEKEY_WIRELESS_CONTROLLER_MS_2DES_KEY1
Definition: xb360.h:41
#define VFUSES_OFFSET
Definition: xb360.h:76
#define REV_ZEPHYR
Definition: xb360.h:94
#define REV_CORONA_PHISON
Definition: xb360.h:99
#define XEKEY_PRIMARY_ACTIVATION_KEY
Definition: xb360.h:37
#define XEKEY_RESERVED_DWORD4
Definition: xb360.h:19
#define XEKEY_WIRELESS_CONTROLLER_MS_2DES_KEY2
Definition: xb360.h:42
#define XEKEY_WIRED_WEBCAM_3P_2DES_KEY1
Definition: xb360.h:53
#define XEKEY_SECONDARY_ACTIVATION_KEY
Definition: xb360.h:38
#define XEKEY_MEMORY_UNIT_3P_2DES_KEY2
Definition: xb360.h:58
#define XEKEY_RESERVED_KEY1
Definition: xb360.h:24
#define XEKEY_CARDEA_PRIVATE_KEY
Definition: xb360.h:63
#define XELL_OFFSET_COUNT
Definition: xb360.h:83
#define XEKEY_RESERVED_KEY3
Definition: xb360.h:26
#define XEKEY_RESTRICTED_HVEXT_LOADER
Definition: xb360.h:16
#define XEKEY_WIRED_CONTROLLER_3P_2DES_KEY1
Definition: xb360.h:55
#define XEKEY_RESERVED_RANDOM_KEY1
Definition: xb360.h:28
#define XEKEY_OTHER_XSM3_DEVICE_MS_2DES_KEY1
Definition: xb360.h:49
#define XEKEY_MEMORY_UNIT_MS_2DES_KEY2
Definition: xb360.h:48
#define REV_WINCHESTER_MMC
Definition: xb360.h:101
#define XEKEY_MANUFACTURING_MODE
Definition: xb360.h:10
#define XEKEY_MEMORY_UNIT_MS_2DES_KEY1
Definition: xb360.h:47
#define XEKEY_WIRED_CONTROLLER_MS_2DES_KEY1
Definition: xb360.h:45
#define XEKEY_RESERVED_QWORD3
Definition: xb360.h:22
#define XEKEY_XEIKA_PRIVATE_KEY
Definition: xb360.h:62
#define XEKEY_MEMORY_UNIT_3P_2DES_KEY1
Definition: xb360.h:57
#define XEKEY_CONSOLE_SERIAL_NUMBER
Definition: xb360.h:30
#define XEKEY_WIRED_WEBCAM_MS_2DES_KEY1
Definition: xb360.h:43
#define XEKEY_CONSOLE_OBFUSCATION_KEY
Definition: xb360.h:33
#define XEKEY_RESERVED_WORD1
Definition: xb360.h:14
#define XEKEY_RESTRICTED_PRIVILEDGES
Definition: xb360.h:20
#define XEKEY_DVD_KEY
Definition: xb360.h:36
#define XEKEY_WIRELESS_CONTROLLER_3P_2DES_KEY2
Definition: xb360.h:52
#define REV_TRINITY
Definition: xb360.h:97
#define XEKEY_WIRED_WEBCAM_3P_2DES_KEY2
Definition: xb360.h:54
#define XEKEY_CONSOLE_CERTIFICATE
Definition: xb360.h:64
#define XEKEY_RESERVED_DWORD2
Definition: xb360.h:17
#define REV_FALCON
Definition: xb360.h:95
#define REV_JASPER
Definition: xb360.h:96
#define XEKEY_RESERVED_DWORD3
Definition: xb360.h:18
#define REV_WINCHESTER
Definition: xb360.h:100
#define XEKEY_RESERVED_QWORD4
Definition: xb360.h:23
#define XEKEY_CONSOLE_PRIVATE_KEY
Definition: xb360.h:61
#define XEKEY_WIRED_WEBCAM_MS_2DES_KEY2
Definition: xb360.h:44
#define XEKEY_RESERVED_RANDOM_KEY2
Definition: xb360.h:29
#define XEKEY_OTHER_XSM3_DEVICE_3P_2DES_KEY1
Definition: xb360.h:59
#define XEKEY_ALTERNATE_KEY_VAULT
Definition: xb360.h:11
#define XEKEY_XEIKA_CERTIFICATE
Definition: xb360.h:65
#define XEKEY_GAME_REGION
Definition: xb360.h:32
#define XEKEY_RESERVED_KEY2
Definition: xb360.h:25
#define XEKEY_OTHER_XSM3_DEVICE_3P_2DES_KEY2
Definition: xb360.h:60
#define XEKEY_OTHER_XSM3_DEVICE_MS_2DES_KEY2
Definition: xb360.h:50
#define REV_UNKNOWN
Definition: xb360.h:102
#define XEKEY_RESERVED_BYTE2
Definition: xb360.h:12
#define XEKEY_GLOBAL_DEVICE_2DES_KEY2
Definition: xb360.h:40
#define XEKEY_MOBO_SERIAL_NUMBER
Definition: xb360.h:31
#define XEKEY_CARDEA_CERTIFICATE
Definition: xb360.h:66
#define XEKEY_WIRED_CONTROLLER_MS_2DES_KEY2
Definition: xb360.h:46
unsigned char pagebuf[MAX_PAGE_SZ]
Definition: xenon_config.c:20
uint64_t xenon_secotp_read_line(int nr)
Definition: xenon_secotp.c:3
unsigned long sfcx_readreg(int addr)
Definition: xenon_sfcx.c:20
int sfcx_is_pageerased(unsigned char *data)
Definition: xenon_sfcx.c:361
int sfcx_read_page(unsigned char *data, int address, int raw)
Definition: xenon_sfcx.c:25
int sfcx_write_page(unsigned char *data, int address)
Definition: xenon_sfcx.c:74
void sfcx_calcecc(unsigned int *data)
Definition: xenon_sfcx.c:211
int sfcx_erase_block(int address)
Definition: xenon_sfcx.c:150
#define SFCX_INITIALIZED
Definition: xenon_sfcx.h:78
#define SFCX_PHISON
Definition: xenon_sfcx.h:16
#define MAX_PAGE_SZ
Definition: xenon_sfcx.h:63
int xenon_smc_ana_read(uint8_t addr, uint32_t *val)
Definition: xenon_smc.c:149
#define XELL_FOOTER
#define XELL_FOOTER_LENGTH
#define XELL_FOOTER_OFFSET
union @15 data
u32 serial
Definition: xenos_edid.h:4
u8 j
Definition: xenos_edid.h:10
u8 k
Definition: xenos_edid.h:9