mirror of
https://github.com/shchmue/Lockpick.git
synced 2024-12-22 14:35:26 +00:00
Merge pull request #19 from HookedBehemoth/master
Fix ticket listing and minor libnx update
This commit is contained in:
commit
b150d20957
|
@ -35,7 +35,6 @@
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "nx/es.h"
|
#include "nx/es.h"
|
||||||
#include "nx/set_ext.h"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TITLEKEY_BUFFER_SIZE 0x40000
|
#define TITLEKEY_BUFFER_SIZE 0x40000
|
||||||
|
@ -486,7 +485,7 @@ void KeyCollection::derive_keys() {
|
||||||
FRESULT fr;
|
FRESULT fr;
|
||||||
FIL save_file;
|
FIL save_file;
|
||||||
|
|
||||||
fsOpenBisStorage(&storage, FsBisStorageId_System);
|
fsOpenBisStorage(&storage, FsBisPartitionId_System);
|
||||||
if (f_mount(&fs, "", 1) ||
|
if (f_mount(&fs, "", 1) ||
|
||||||
f_chdir("/save") ||
|
f_chdir("/save") ||
|
||||||
f_open(&save_file, "8000000000000043", FA_READ | FA_OPEN_EXISTING))
|
f_open(&save_file, "8000000000000043", FA_READ | FA_OPEN_EXISTING))
|
||||||
|
@ -592,7 +591,7 @@ void KeyCollection::get_titlekeys() {
|
||||||
esInitialize();
|
esInitialize();
|
||||||
esCountCommonTicket(&common_count);
|
esCountCommonTicket(&common_count);
|
||||||
esCountPersonalizedTicket(&personalized_count);
|
esCountPersonalizedTicket(&personalized_count);
|
||||||
NcmRightsId common_rights_ids[common_count], personalized_rights_ids[personalized_count];
|
RightsId common_rights_ids[common_count], personalized_rights_ids[personalized_count];
|
||||||
esListCommonTicket(&ids_written, common_rights_ids, sizeof(common_rights_ids));
|
esListCommonTicket(&ids_written, common_rights_ids, sizeof(common_rights_ids));
|
||||||
esListPersonalizedTicket(&ids_written, personalized_rights_ids, sizeof(personalized_rights_ids));
|
esListPersonalizedTicket(&ids_written, personalized_rights_ids, sizeof(personalized_rights_ids));
|
||||||
esExit();
|
esExit();
|
||||||
|
@ -608,27 +607,27 @@ void KeyCollection::get_titlekeys() {
|
||||||
std::unordered_set<std::string> rights_ids;
|
std::unordered_set<std::string> rights_ids;
|
||||||
for (size_t i = 0; i < common_count; i++) {
|
for (size_t i = 0; i < common_count; i++) {
|
||||||
for (size_t j = 0; j < 0x10; j++) {
|
for (size_t j = 0; j < 0x10; j++) {
|
||||||
sprintf(&rights_id_string[j*2], "%02x", common_rights_ids[i].rights_id.c[j]);
|
sprintf(&rights_id_string[j*2], "%02x", common_rights_ids[i].c[j]);
|
||||||
}
|
}
|
||||||
rights_ids.insert(rights_id_string);
|
rights_ids.insert(rights_id_string);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < personalized_count; i++) {
|
for (size_t i = 0; i < personalized_count; i++) {
|
||||||
for (size_t j = 0; j < 0x10; j++) {
|
for (size_t j = 0; j < 0x10; j++) {
|
||||||
sprintf(&rights_id_string[j*2], "%02x", personalized_rights_ids[i].rights_id.c[j]);
|
sprintf(&rights_id_string[j*2], "%02x", personalized_rights_ids[i].c[j]);
|
||||||
}
|
}
|
||||||
rights_ids.insert(rights_id_string);
|
rights_ids.insert(rights_id_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get extended eticket RSA key from PRODINFO
|
// get extended eticket RSA key from PRODINFO
|
||||||
u8 eticket_data[0x244] = {};
|
SetCalRsa2048DeviceKey eticket_data = {};
|
||||||
|
|
||||||
setcalInitialize();
|
setcalInitialize();
|
||||||
setcalGetEticketDeviceKey(eticket_data);
|
setcalGetEticketDeviceKey(&eticket_data);
|
||||||
setcalExit();
|
setcalExit();
|
||||||
|
|
||||||
byte_vector dec_keypair = eticket_rsa_kek.aes_decrypt_ctr(
|
byte_vector dec_keypair = eticket_rsa_kek.aes_decrypt_ctr(
|
||||||
byte_vector(eticket_data + 0x14, eticket_data + 0x244),
|
byte_vector(eticket_data.key + 0x10, eticket_data.key + 0x240),
|
||||||
byte_vector(eticket_data + 4, eticket_data + 0x14)
|
byte_vector(eticket_data.key, eticket_data.key + 0x10)
|
||||||
);
|
);
|
||||||
|
|
||||||
// public exponent must be 65537 == 0x10001 (big endian)
|
// public exponent must be 65537 == 0x10001 (big endian)
|
||||||
|
@ -646,7 +645,7 @@ void KeyCollection::get_titlekeys() {
|
||||||
// map of all found rights ids and corresponding titlekeys
|
// map of all found rights ids and corresponding titlekeys
|
||||||
std::unordered_map<std::string, std::string> titlekeys;
|
std::unordered_map<std::string, std::string> titlekeys;
|
||||||
|
|
||||||
fsOpenBisStorage(&storage, FsBisStorageId_System);
|
fsOpenBisStorage(&storage, FsBisPartitionId_System);
|
||||||
if (f_mount(&fs, "", 1) || f_chdir("/save")) return;
|
if (f_mount(&fs, "", 1) || f_chdir("/save")) return;
|
||||||
if (f_open(&save_file, "80000000000000e1", FA_READ | FA_OPEN_EXISTING)) return;
|
if (f_open(&save_file, "80000000000000e1", FA_READ | FA_OPEN_EXISTING)) return;
|
||||||
while ((common_count != 0) && (titlekeys_dumped < common_count)) {
|
while ((common_count != 0) && (titlekeys_dumped < common_count)) {
|
||||||
|
|
|
@ -101,7 +101,7 @@ void KeyLocation::get_from_memory(u64 tid, u8 seg_mask) {
|
||||||
|
|
||||||
void KeyLocation::get_keyblobs() {
|
void KeyLocation::get_keyblobs() {
|
||||||
FsStorage boot0;
|
FsStorage boot0;
|
||||||
fsOpenBisStorage(&boot0, FsBisStorageId_Boot0);
|
fsOpenBisStorage(&boot0, FsBisPartitionId_BootPartition1Root);
|
||||||
data.resize(0x200 * KNOWN_KEYBLOBS);
|
data.resize(0x200 * KNOWN_KEYBLOBS);
|
||||||
fsStorageRead(&boot0, KEYBLOB_OFFSET, data.data(), data.size());
|
fsStorageRead(&boot0, KEYBLOB_OFFSET, data.data(), data.size());
|
||||||
fsStorageClose(&boot0);
|
fsStorageClose(&boot0);
|
||||||
|
|
|
@ -17,56 +17,48 @@ void _esCleanup() {
|
||||||
serviceClose(&g_esSrv);
|
serviceClose(&g_esSrv);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result esCountCommonTicket(u32 *num_tickets)
|
Result esCountCommonTicket(u32 *out_count)
|
||||||
{
|
{
|
||||||
struct {
|
|
||||||
u32 num_tickets;
|
u32 num_tickets;
|
||||||
} out;
|
|
||||||
|
|
||||||
Result rc = serviceDispatchOut(&g_esSrv, 9, out);
|
Result rc = serviceDispatchOut(&g_esSrv, 9, num_tickets);
|
||||||
if (R_SUCCEEDED(rc) && num_tickets) *num_tickets = out.num_tickets;
|
if (R_SUCCEEDED(rc) && out_count) *out_count = num_tickets;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result esCountPersonalizedTicket(u32 *num_tickets)
|
Result esCountPersonalizedTicket(u32 *out_count)
|
||||||
{
|
{
|
||||||
struct {
|
|
||||||
u32 num_tickets;
|
u32 num_tickets;
|
||||||
} out;
|
|
||||||
|
|
||||||
Result rc = serviceDispatchOut(&g_esSrv, 10, out);
|
Result rc = serviceDispatchOut(&g_esSrv, 10, num_tickets);
|
||||||
if (R_SUCCEEDED(rc) && num_tickets) *num_tickets = out.num_tickets;
|
if (R_SUCCEEDED(rc) && out_count) *out_count = num_tickets;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result esListCommonTicket(u32 *numRightsIdsWritten, NcmRightsId *outBuf, size_t bufSize)
|
Result esListCommonTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize)
|
||||||
{
|
{
|
||||||
struct {
|
|
||||||
u32 num_rights_ids_written;
|
u32 num_rights_ids_written;
|
||||||
} out;
|
|
||||||
|
|
||||||
Result rc = serviceDispatchInOut(&g_esSrv, 11, *numRightsIdsWritten, out,
|
Result rc = serviceDispatchOut(&g_esSrv, 11, num_rights_ids_written,
|
||||||
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
||||||
.buffers = { { outBuf, bufSize } },
|
.buffers = { { outBuf, bufSize } },
|
||||||
);
|
);
|
||||||
if (R_SUCCEEDED(rc) && numRightsIdsWritten) *numRightsIdsWritten = out.num_rights_ids_written;
|
if (R_SUCCEEDED(rc) && numRightsIdsWritten) *numRightsIdsWritten = num_rights_ids_written;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result esListPersonalizedTicket(u32 *numRightsIdsWritten, NcmRightsId *outBuf, size_t bufSize)
|
Result esListPersonalizedTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize)
|
||||||
{
|
{
|
||||||
struct {
|
|
||||||
u32 num_rights_ids_written;
|
u32 num_rights_ids_written;
|
||||||
} out;
|
|
||||||
|
|
||||||
Result rc = serviceDispatchInOut(&g_esSrv, 12, *numRightsIdsWritten, out,
|
Result rc = serviceDispatchOut(&g_esSrv, 12, num_rights_ids_written,
|
||||||
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
||||||
.buffers = { { outBuf, bufSize } },
|
.buffers = { { outBuf, bufSize } },
|
||||||
);
|
);
|
||||||
if (R_SUCCEEDED(rc) && numRightsIdsWritten) *numRightsIdsWritten = out.num_rights_ids_written;
|
if (R_SUCCEEDED(rc) && numRightsIdsWritten) *numRightsIdsWritten = num_rights_ids_written;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
|
@ -3,10 +3,14 @@
|
||||||
#include <switch/types.h>
|
#include <switch/types.h>
|
||||||
#include <switch/services/ncm.h>
|
#include <switch/services/ncm.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u8 c[0x10];
|
||||||
|
} RightsId;
|
||||||
|
|
||||||
Result esInitialize();
|
Result esInitialize();
|
||||||
void esExit();
|
void esExit();
|
||||||
|
|
||||||
Result esCountCommonTicket(u32 *num_tickets); //9
|
Result esCountCommonTicket(u32 *num_tickets); //9
|
||||||
Result esCountPersonalizedTicket(u32 *num_tickets); // 10
|
Result esCountPersonalizedTicket(u32 *num_tickets); // 10
|
||||||
Result esListCommonTicket(u32 *numRightsIdsWritten, NcmRightsId *outBuf, size_t bufSize);
|
Result esListCommonTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize);
|
||||||
Result esListPersonalizedTicket(u32 *numRightsIdsWritten, NcmRightsId *outBuf, size_t bufSize);
|
Result esListPersonalizedTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize);
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
#include "set_ext.h"
|
|
||||||
|
|
||||||
#include "../service_guard.h"
|
|
||||||
|
|
||||||
#include <switch/services/sm.h>
|
|
||||||
#include <switch/types.h>
|
|
||||||
|
|
||||||
static Service g_setcalSrv;
|
|
||||||
|
|
||||||
NX_GENERATE_SERVICE_GUARD(setcal);
|
|
||||||
|
|
||||||
Result _setcalInitialize() {
|
|
||||||
return smGetService(&g_setcalSrv, "set:cal");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _setcalCleanup() {
|
|
||||||
serviceClose(&g_setcalSrv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result setcalGetEticketDeviceKey(void *key)
|
|
||||||
{
|
|
||||||
return serviceDispatch(&g_setcalSrv, 21,
|
|
||||||
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
|
||||||
.buffers = { { key, 0x244 } },
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <switch/result.h>
|
|
||||||
|
|
||||||
Result setcalInitialize(void);
|
|
||||||
void setcalExit(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Gets the extended ETicket RSA-2048 Key from CAL0
|
|
||||||
* @param key Pointer to 0x244-byte output buffer.
|
|
||||||
*/
|
|
||||||
Result setcalGetEticketDeviceKey(void *key);
|
|
Loading…
Reference in a new issue