diff options
-rw-r--r-- | source/KeyCollection.cpp | 19 | ||||
-rw-r--r-- | source/KeyLocation.cpp | 2 | ||||
-rw-r--r-- | source/nx/es.c | 42 | ||||
-rw-r--r-- | source/nx/es.h | 8 | ||||
-rw-r--r-- | source/nx/set_ext.c | 26 | ||||
-rw-r--r-- | source/nx/set_ext.h | 12 |
6 files changed, 33 insertions, 76 deletions
diff --git a/source/KeyCollection.cpp b/source/KeyCollection.cpp index 897eb5b..44fb084 100644 --- a/source/KeyCollection.cpp +++ b/source/KeyCollection.cpp | |||
@@ -35,7 +35,6 @@ | |||
35 | 35 | ||
36 | extern "C" { | 36 | extern "C" { |
37 | #include "nx/es.h" | 37 | #include "nx/es.h" |
38 | #include "nx/set_ext.h" | ||
39 | } | 38 | } |
40 | 39 | ||
41 | #define TITLEKEY_BUFFER_SIZE 0x40000 | 40 | #define TITLEKEY_BUFFER_SIZE 0x40000 |
@@ -486,7 +485,7 @@ void KeyCollection::derive_keys() { | |||
486 | FRESULT fr; | 485 | FRESULT fr; |
487 | FIL save_file; | 486 | FIL save_file; |
488 | 487 | ||
489 | fsOpenBisStorage(&storage, FsBisStorageId_System); | 488 | fsOpenBisStorage(&storage, FsBisPartitionId_System); |
490 | if (f_mount(&fs, "", 1) || | 489 | if (f_mount(&fs, "", 1) || |
491 | f_chdir("/save") || | 490 | f_chdir("/save") || |
492 | f_open(&save_file, "8000000000000043", FA_READ | FA_OPEN_EXISTING)) | 491 | f_open(&save_file, "8000000000000043", FA_READ | FA_OPEN_EXISTING)) |
@@ -592,7 +591,7 @@ void KeyCollection::get_titlekeys() { | |||
592 | esInitialize(); | 591 | esInitialize(); |
593 | esCountCommonTicket(&common_count); | 592 | esCountCommonTicket(&common_count); |
594 | esCountPersonalizedTicket(&personalized_count); | 593 | esCountPersonalizedTicket(&personalized_count); |
595 | NcmRightsId common_rights_ids[common_count], personalized_rights_ids[personalized_count]; | 594 | RightsId common_rights_ids[common_count], personalized_rights_ids[personalized_count]; |
596 | esListCommonTicket(&ids_written, common_rights_ids, sizeof(common_rights_ids)); | 595 | esListCommonTicket(&ids_written, common_rights_ids, sizeof(common_rights_ids)); |
597 | esListPersonalizedTicket(&ids_written, personalized_rights_ids, sizeof(personalized_rights_ids)); | 596 | esListPersonalizedTicket(&ids_written, personalized_rights_ids, sizeof(personalized_rights_ids)); |
598 | esExit(); | 597 | esExit(); |
@@ -608,27 +607,27 @@ void KeyCollection::get_titlekeys() { | |||
608 | std::unordered_set<std::string> rights_ids; | 607 | std::unordered_set<std::string> rights_ids; |
609 | for (size_t i = 0; i < common_count; i++) { | 608 | for (size_t i = 0; i < common_count; i++) { |
610 | for (size_t j = 0; j < 0x10; j++) { | 609 | for (size_t j = 0; j < 0x10; j++) { |
611 | sprintf(&rights_id_string[j*2], "%02x", common_rights_ids[i].rights_id.c[j]); | 610 | sprintf(&rights_id_string[j*2], "%02x", common_rights_ids[i].c[j]); |
612 | } | 611 | } |
613 | rights_ids.insert(rights_id_string); | 612 | rights_ids.insert(rights_id_string); |
614 | } | 613 | } |
615 | for (size_t i = 0; i < personalized_count; i++) { | 614 | for (size_t i = 0; i < personalized_count; i++) { |
616 | for (size_t j = 0; j < 0x10; j++) { | 615 | for (size_t j = 0; j < 0x10; j++) { |
617 | sprintf(&rights_id_string[j*2], "%02x", personalized_rights_ids[i].rights_id.c[j]); | 616 | sprintf(&rights_id_string[j*2], "%02x", personalized_rights_ids[i].c[j]); |
618 | } | 617 | } |
619 | rights_ids.insert(rights_id_string); | 618 | rights_ids.insert(rights_id_string); |
620 | } | 619 | } |
621 | 620 | ||
622 | // get extended eticket RSA key from PRODINFO | 621 | // get extended eticket RSA key from PRODINFO |
623 | u8 eticket_data[0x244] = {}; | 622 | SetCalRsa2048DeviceKey eticket_data = {}; |
624 | 623 | ||
625 | setcalInitialize(); | 624 | setcalInitialize(); |
626 | setcalGetEticketDeviceKey(eticket_data); | 625 | setcalGetEticketDeviceKey(&eticket_data); |
627 | setcalExit(); | 626 | setcalExit(); |
628 | 627 | ||
629 | byte_vector dec_keypair = eticket_rsa_kek.aes_decrypt_ctr( | 628 | byte_vector dec_keypair = eticket_rsa_kek.aes_decrypt_ctr( |
630 | byte_vector(eticket_data + 0x14, eticket_data + 0x244), | 629 | byte_vector(eticket_data.key + 0x10, eticket_data.key + 0x240), |
631 | byte_vector(eticket_data + 4, eticket_data + 0x14) | 630 | byte_vector(eticket_data.key, eticket_data.key + 0x10) |
632 | ); | 631 | ); |
633 | 632 | ||
634 | // public exponent must be 65537 == 0x10001 (big endian) | 633 | // public exponent must be 65537 == 0x10001 (big endian) |
@@ -646,7 +645,7 @@ void KeyCollection::get_titlekeys() { | |||
646 | // map of all found rights ids and corresponding titlekeys | 645 | // map of all found rights ids and corresponding titlekeys |
647 | std::unordered_map<std::string, std::string> titlekeys; | 646 | std::unordered_map<std::string, std::string> titlekeys; |
648 | 647 | ||
649 | fsOpenBisStorage(&storage, FsBisStorageId_System); | 648 | fsOpenBisStorage(&storage, FsBisPartitionId_System); |
650 | if (f_mount(&fs, "", 1) || f_chdir("/save")) return; | 649 | if (f_mount(&fs, "", 1) || f_chdir("/save")) return; |
651 | if (f_open(&save_file, "80000000000000e1", FA_READ | FA_OPEN_EXISTING)) return; | 650 | if (f_open(&save_file, "80000000000000e1", FA_READ | FA_OPEN_EXISTING)) return; |
652 | while ((common_count != 0) && (titlekeys_dumped < common_count)) { | 651 | while ((common_count != 0) && (titlekeys_dumped < common_count)) { |
diff --git a/source/KeyLocation.cpp b/source/KeyLocation.cpp index ba5cee7..eb1fe27 100644 --- a/source/KeyLocation.cpp +++ b/source/KeyLocation.cpp | |||
@@ -101,7 +101,7 @@ void KeyLocation::get_from_memory(u64 tid, u8 seg_mask) { | |||
101 | 101 | ||
102 | void KeyLocation::get_keyblobs() { | 102 | void KeyLocation::get_keyblobs() { |
103 | FsStorage boot0; | 103 | FsStorage boot0; |
104 | fsOpenBisStorage(&boot0, FsBisStorageId_Boot0); | 104 | fsOpenBisStorage(&boot0, FsBisPartitionId_BootPartition1Root); |
105 | data.resize(0x200 * KNOWN_KEYBLOBS); | 105 | data.resize(0x200 * KNOWN_KEYBLOBS); |
106 | fsStorageRead(&boot0, KEYBLOB_OFFSET, data.data(), data.size()); | 106 | fsStorageRead(&boot0, KEYBLOB_OFFSET, data.data(), data.size()); |
107 | fsStorageClose(&boot0); | 107 | fsStorageClose(&boot0); |
diff --git a/source/nx/es.c b/source/nx/es.c index fbd7dca..ed0c6f0 100644 --- a/source/nx/es.c +++ b/source/nx/es.c | |||
@@ -17,56 +17,48 @@ void _esCleanup() { | |||
17 | serviceClose(&g_esSrv); | 17 | serviceClose(&g_esSrv); |
18 | } | 18 | } |
19 | 19 | ||
20 | Result esCountCommonTicket(u32 *num_tickets) | 20 | Result esCountCommonTicket(u32 *out_count) |
21 | { | 21 | { |
22 | struct { | 22 | u32 num_tickets; |
23 | u32 num_tickets; | ||
24 | } out; | ||
25 | 23 | ||
26 | Result rc = serviceDispatchOut(&g_esSrv, 9, out); | 24 | Result rc = serviceDispatchOut(&g_esSrv, 9, num_tickets); |
27 | if (R_SUCCEEDED(rc) && num_tickets) *num_tickets = out.num_tickets; | 25 | if (R_SUCCEEDED(rc) && out_count) *out_count = num_tickets; |
28 | 26 | ||
29 | return rc; | 27 | return rc; |
30 | } | 28 | } |
31 | 29 | ||
32 | Result esCountPersonalizedTicket(u32 *num_tickets) | 30 | Result esCountPersonalizedTicket(u32 *out_count) |
33 | { | 31 | { |
34 | struct { | 32 | u32 num_tickets; |
35 | u32 num_tickets; | ||
36 | } out; | ||
37 | 33 | ||
38 | Result rc = serviceDispatchOut(&g_esSrv, 10, out); | 34 | Result rc = serviceDispatchOut(&g_esSrv, 10, num_tickets); |
39 | if (R_SUCCEEDED(rc) && num_tickets) *num_tickets = out.num_tickets; | 35 | if (R_SUCCEEDED(rc) && out_count) *out_count = num_tickets; |
40 | 36 | ||
41 | return rc; | 37 | return rc; |
42 | } | 38 | } |
43 | 39 | ||
44 | Result esListCommonTicket(u32 *numRightsIdsWritten, NcmRightsId *outBuf, size_t bufSize) | 40 | Result esListCommonTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize) |
45 | { | 41 | { |
46 | struct { | 42 | u32 num_rights_ids_written; |
47 | u32 num_rights_ids_written; | ||
48 | } out; | ||
49 | 43 | ||
50 | Result rc = serviceDispatchInOut(&g_esSrv, 11, *numRightsIdsWritten, out, | 44 | Result rc = serviceDispatchOut(&g_esSrv, 11, num_rights_ids_written, |
51 | .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, | 45 | .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, |
52 | .buffers = { { outBuf, bufSize } }, | 46 | .buffers = { { outBuf, bufSize } }, |
53 | ); | 47 | ); |
54 | if (R_SUCCEEDED(rc) && numRightsIdsWritten) *numRightsIdsWritten = out.num_rights_ids_written; | 48 | if (R_SUCCEEDED(rc) && numRightsIdsWritten) *numRightsIdsWritten = num_rights_ids_written; |
55 | 49 | ||
56 | return rc; | 50 | return rc; |
57 | } | 51 | } |
58 | 52 | ||
59 | Result esListPersonalizedTicket(u32 *numRightsIdsWritten, NcmRightsId *outBuf, size_t bufSize) | 53 | Result esListPersonalizedTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize) |
60 | { | 54 | { |
61 | struct { | 55 | u32 num_rights_ids_written; |
62 | u32 num_rights_ids_written; | ||
63 | } out; | ||
64 | 56 | ||
65 | Result rc = serviceDispatchInOut(&g_esSrv, 12, *numRightsIdsWritten, out, | 57 | Result rc = serviceDispatchOut(&g_esSrv, 12, num_rights_ids_written, |
66 | .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, | 58 | .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, |
67 | .buffers = { { outBuf, bufSize } }, | 59 | .buffers = { { outBuf, bufSize } }, |
68 | ); | 60 | ); |
69 | if (R_SUCCEEDED(rc) && numRightsIdsWritten) *numRightsIdsWritten = out.num_rights_ids_written; | 61 | if (R_SUCCEEDED(rc) && numRightsIdsWritten) *numRightsIdsWritten = num_rights_ids_written; |
70 | 62 | ||
71 | return rc; | 63 | return rc; |
72 | } \ No newline at end of file | 64 | } |
diff --git a/source/nx/es.h b/source/nx/es.h index f1ad03a..a43e22d 100644 --- a/source/nx/es.h +++ b/source/nx/es.h | |||
@@ -3,10 +3,14 @@ | |||
3 | #include <switch/types.h> | 3 | #include <switch/types.h> |
4 | #include <switch/services/ncm.h> | 4 | #include <switch/services/ncm.h> |
5 | 5 | ||
6 | typedef struct { | ||
7 | u8 c[0x10]; | ||
8 | } RightsId; | ||
9 | |||
6 | Result esInitialize(); | 10 | Result esInitialize(); |
7 | void esExit(); | 11 | void esExit(); |
8 | 12 | ||
9 | Result esCountCommonTicket(u32 *num_tickets); //9 | 13 | Result esCountCommonTicket(u32 *num_tickets); //9 |
10 | Result esCountPersonalizedTicket(u32 *num_tickets); // 10 | 14 | Result esCountPersonalizedTicket(u32 *num_tickets); // 10 |
11 | Result esListCommonTicket(u32 *numRightsIdsWritten, NcmRightsId *outBuf, size_t bufSize); | 15 | Result esListCommonTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize); |
12 | Result esListPersonalizedTicket(u32 *numRightsIdsWritten, NcmRightsId *outBuf, size_t bufSize); \ No newline at end of file | 16 | Result esListPersonalizedTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize); |
diff --git a/source/nx/set_ext.c b/source/nx/set_ext.c deleted file mode 100644 index 2ccef6c..0000000 --- a/source/nx/set_ext.c +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
1 | #include "set_ext.h" | ||
2 | |||
3 | #include "../service_guard.h" | ||
4 | |||
5 | #include <switch/services/sm.h> | ||
6 | #include <switch/types.h> | ||
7 | |||
8 | static Service g_setcalSrv; | ||
9 | |||
10 | NX_GENERATE_SERVICE_GUARD(setcal); | ||
11 | |||
12 | Result _setcalInitialize() { | ||
13 | return smGetService(&g_setcalSrv, "set:cal"); | ||
14 | } | ||
15 | |||
16 | void _setcalCleanup() { | ||
17 | serviceClose(&g_setcalSrv); | ||
18 | } | ||
19 | |||
20 | Result setcalGetEticketDeviceKey(void *key) | ||
21 | { | ||
22 | return serviceDispatch(&g_setcalSrv, 21, | ||
23 | .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, | ||
24 | .buffers = { { key, 0x244 } }, | ||
25 | ); | ||
26 | } \ No newline at end of file | ||
diff --git a/source/nx/set_ext.h b/source/nx/set_ext.h deleted file mode 100644 index 9777cd6..0000000 --- a/source/nx/set_ext.h +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | #pragma once | ||
2 | |||
3 | #include <switch/result.h> | ||
4 | |||
5 | Result setcalInitialize(void); | ||
6 | void setcalExit(void); | ||
7 | |||
8 | /** | ||
9 | * @brief Gets the extended ETicket RSA-2048 Key from CAL0 | ||
10 | * @param key Pointer to 0x244-byte output buffer. | ||
11 | */ | ||
12 | Result setcalGetEticketDeviceKey(void *key); \ No newline at end of file | ||