-
-
Save flatz/22215327864d7512e52268f9c9c51cd8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int dump_raw_keys(unsigned int* key_ids, size_t key_count, unsigned int max_key_size, uint8_t** key_data, size_t* key_data_size) { | |
uint8_t* kd = NULL; | |
size_t kds; | |
void* buf = NULL, *m_buf = NULL; | |
struct sbl_map_list_entry* d_buf = NULL; | |
size_t buf_size = PAGE_SIZE; | |
struct ccp_req req; | |
struct ccp_msg msg; | |
size_t data_size = 0x10; | |
uint8_t current_key[0x40]; | |
uint8_t real_hash[0x20], our_hash[0x20]; | |
unsigned int key_index, key_size; | |
uint8_t* ckd; | |
unsigned int i, j; | |
size_t c; | |
int found; | |
int ret; | |
//dprintf("Allocating memory for key data buffer...\n"); | |
kds = (max_key_size + sizeof(int)) * key_count; | |
kd = (uint8_t*)alloc(kds); | |
if (!kd) { | |
//dprintf("Failed.\n"); | |
ret = ENOMEM; | |
goto error; | |
} | |
memset(kd, 0, kds); | |
memset(&req, 0, sizeof(req)); | |
memset(&msg, 0, sizeof(msg)); | |
TAILQ_INIT(&req.msgs); | |
TAILQ_INSERT_TAIL(&req.msgs, &msg, next); | |
//dprintf("Allocating memory for data buffer...\n"); | |
buf = alloc(buf_size); | |
if (!buf) { | |
//dprintf("Failed.\n"); | |
ret = ENOMEM; | |
goto error; | |
} | |
//dprintf("Data buffer CPU address: %p\n", buf); | |
memset(buf, 0, buf_size); | |
//dprintf("Filling data buffer with random data...\n"); | |
for (i = 0; i < data_size; ++i) | |
*((uint8_t*)buf + i) = (i + 1) & 0xFF; | |
//dprintf("Mapping data buffer to GPU...\n"); | |
ret = sceSblDriverMapPages(&m_buf, buf, BYTES_TO_PAGES(buf_size), 0x61, NULL, &d_buf); | |
if (ret != 0) { | |
//dprintf("Failed.\n"); | |
goto error; | |
} | |
//dprintf("Data buffer GPU address: %p (d: %p)\n", m_buf, d_buf); | |
for (c = 0; c < key_count; ++c) { | |
key_index = key_ids[c]; | |
ckd = kd + (max_key_size + sizeof(int)) * c; | |
//dprintf("Bruteforcing key index: 0x%04X\n", key_index); | |
memset(current_key, 0, sizeof(current_key)); | |
memset(real_hash, 0, sizeof(real_hash)); | |
memset(our_hash, 0, sizeof(our_hash)); | |
for (key_size = 0; key_size < max_key_size; ++key_size) { | |
memset(&msg.op, 0, sizeof(msg.op)); | |
msg.op.hmac.cmd = 0x09034000 | CCP_USE_KEY_FROM_SLOT; | |
msg.op.hmac.data_size = data_size; | |
msg.op.hmac.data = buf; | |
msg.op.hmac.data_size_bits = data_size * 8; | |
msg.op.hmac.key_index = key_index; | |
msg.op.hmac.key_size = key_size + 1; | |
//dprintf("Preparing crypto request...\n"); | |
ret = sceSblServiceCrypt(&req); | |
if (ret != 0) { | |
*(int*)(ckd + max_key_size) = ret; | |
//dprintf("sceSblServiceCrypt(index) failed (code: 0x%"PRIX32").\n", ret); | |
//dprintf("\t0x%04X: N/A\n", key_index); | |
break; | |
} | |
memcpy(real_hash, msg.op.hmac.hash, sizeof(real_hash)); | |
found = 0; | |
for (i = 0; i < 256; ++i) { | |
current_key[key_size] = (uint8_t)i; | |
memset(&msg.op, 0, sizeof(msg.op)); | |
msg.op.hmac.cmd = 0x09034000; | |
msg.op.hmac.data_size = data_size; | |
msg.op.hmac.data = buf; | |
msg.op.hmac.data_size_bits = data_size * 8; | |
for (j = 0; j < (key_size + 1); ++j) | |
msg.op.hmac.key[(key_size + 1) - j - 1] = current_key[j]; /* reversed order */ | |
msg.op.hmac.key_size = key_size + 1; | |
//dprintf("Preparing crypto request...\n"); | |
ret = sceSblServiceCrypt(&req); | |
if (ret != 0) | |
break; | |
memcpy(our_hash, msg.op.hmac.hash, sizeof(our_hash)); | |
if (memcmp(real_hash, our_hash, sizeof(real_hash)) == 0) { | |
current_key[key_size] = (uint8_t)i; | |
found = 1; | |
break; | |
} | |
} | |
if (ret != 0) { | |
*(int*)(ckd + max_key_size) = ret; | |
//dprintf("sceSblServiceCrypt(key) failed (code: 0x%"PRIX32").\n", ret); | |
break; | |
} | |
if (found) { | |
if (key_size == max_key_size - 1) { | |
*(int*)(ckd + max_key_size) = 0; | |
for (i = 0; i < max_key_size; ++i) | |
ckd[i] = current_key[max_key_size - i - 1]; | |
} | |
} else { | |
*(int*)(ckd + max_key_size) = ESRCH; | |
//dprintf("\tNOT FOUND\n"); | |
} | |
} | |
} | |
ret = 0; | |
if (key_data) { | |
*key_data = kd; | |
kd = NULL; | |
} | |
if (key_data_size) | |
*key_data_size = kds; | |
error: | |
if (d_buf) { | |
//dprintf("Unmapping data buffer from GPU...\n"); | |
sceSblDriverUnmapPages(d_buf); | |
} | |
if (buf) { | |
//dprintf("Freeing memory of data buffer...\n"); | |
dealloc(buf); | |
} | |
if (kd) { | |
//dprintf("Freeing memory of key data buffer...\n"); | |
dealloc(kd); | |
} | |
return ret; | |
} | |
int dump_gen_keys(unsigned int cmd, int use_hmac, unsigned int max_key_size, unsigned int* key_ids, size_t key_count, uint8_t** key_data, size_t* key_data_size) { | |
uint8_t* kd = NULL; | |
size_t kds; | |
void* buf = NULL, *m_buf = NULL; | |
struct sbl_map_list_entry* d_buf = NULL; | |
size_t buf_size = PAGE_SIZE; | |
struct ccp_req req; | |
struct ccp_msg msg; | |
size_t data_size = 0x80; | |
uint8_t current_key[0x40]; | |
uint8_t real_hash[0x20], our_hash[0x20]; | |
unsigned int key_index, key_size, key_index_mod; | |
unsigned int key_handle = 0; | |
union sbl_key_desc key_desc; | |
uint8_t* ckd; | |
unsigned int i, j; | |
size_t c; | |
int found; | |
int ret; | |
//dprintf("Allocating memory for key data buffer...\n"); | |
kds = (max_key_size + sizeof(int)) * key_count; | |
kd = (uint8_t*)alloc(kds); | |
if (!kd) { | |
//dprintf("Failed.\n"); | |
ret = ENOMEM; | |
goto error; | |
} | |
memset(kd, 0, kds); | |
memset(&req, 0, sizeof(req)); | |
memset(&msg, 0, sizeof(msg)); | |
TAILQ_INIT(&req.msgs); | |
TAILQ_INSERT_TAIL(&req.msgs, &msg, next); | |
//dprintf("Allocating memory for data buffer...\n"); | |
buf = alloc(buf_size); | |
if (!buf) { | |
//dprintf("Failed.\n"); | |
ret = ENOMEM; | |
goto error; | |
} | |
//dprintf("Data buffer CPU address: %p\n", buf); | |
memset(buf, 0, buf_size); | |
//dprintf("Filling data buffer with random data...\n"); | |
for (i = 0; i < data_size; ++i) | |
*((uint8_t*)buf + i) = (i + 1) & 0xFF; | |
//dprintf("Mapping data buffer to GPU...\n"); | |
ret = sceSblDriverMapPages(&m_buf, buf, BYTES_TO_PAGES(buf_size), 0x61, NULL, &d_buf); | |
if (ret != 0) { | |
//dprintf("Failed.\n"); | |
goto error; | |
} | |
//dprintf("Data buffer GPU address: %p (d: %p)\n", m_buf, d_buf); | |
key_index_mod = use_hmac ? 0x8000 : 0; | |
for (c = 0; c < key_count; ++c) { | |
key_index = key_ids[c]; | |
ckd = kd + (max_key_size + sizeof(int)) * c; | |
//dprintf("Bruteforcing key index: 0x%04X\n", key_index | key_index_mod); | |
memset(&key_desc, 0, sizeof(key_desc)); | |
key_desc.portability.cmd = cmd; | |
key_desc.portability.key_id = key_index | key_index_mod; | |
key_handle = 0; | |
ret = sceSblKeymgrSetKey(&key_desc, &key_handle); | |
if (ret != 0) { | |
*(int*)(ckd + max_key_size) = ret; | |
//dprintf("sceSblKeymgrSetKey() failed (code: 0x%"PRIX32").\n", ret); | |
//dprintf("\t0x%04X: N/A\n", key_index | key_index_mod); | |
break; | |
} | |
memset(current_key, 0, sizeof(current_key)); | |
memset(real_hash, 0, sizeof(real_hash)); | |
memset(our_hash, 0, sizeof(our_hash)); | |
for (key_size = 0; key_size < max_key_size; ++key_size) { | |
memset(&msg.op, 0, sizeof(msg.op)); | |
msg.op.hmac.cmd = 0x09034000 | CCP_USE_KEY_HANDLE; | |
msg.op.hmac.data_size = data_size; | |
msg.op.hmac.data = buf; | |
msg.op.hmac.data_size_bits = data_size * 8; | |
msg.op.hmac.key_index = key_handle; | |
msg.op.hmac.key_size = key_size + 1; | |
//dprintf("Preparing crypto request...\n"); | |
ret = sceSblServiceCrypt(&req); | |
if (ret != 0) { | |
*(int*)(ckd + max_key_size) = ret; | |
//dprintf("sceSblServiceCrypt(index) failed (code: 0x%"PRIX32").\n", ret); | |
//dprintf("\t0x%04X: N/A\n", key_index | key_index_mod); | |
break; | |
} | |
memcpy(real_hash, msg.op.hmac.hash, sizeof(real_hash)); | |
found = 0; | |
for (i = 0; i < 256; ++i) { | |
current_key[key_size] = (uint8_t)i; | |
memset(&msg.op, 0, sizeof(msg.op)); | |
msg.op.hmac.cmd = 0x09034000; | |
msg.op.hmac.data_size = data_size; | |
msg.op.hmac.data = buf; | |
msg.op.hmac.data_size_bits = data_size * 8; | |
for (j = 0; j < (key_size + 1); ++j) | |
msg.op.hmac.key[(key_size + 1) - j - 1] = current_key[j]; /* reversed order */ | |
msg.op.hmac.key_size = key_size + 1; | |
//dprintf("Preparing crypto request...\n"); | |
ret = sceSblServiceCrypt(&req); | |
if (ret != 0) | |
break; | |
memcpy(our_hash, msg.op.hmac.hash, sizeof(our_hash)); | |
if (memcmp(real_hash, our_hash, sizeof(real_hash)) == 0) { | |
current_key[key_size] = (uint8_t)i; | |
found = 1; | |
break; | |
} | |
} | |
if (ret != 0) { | |
*(int*)(ckd + max_key_size) = ret; | |
//dprintf("sceSblServiceCrypt(key) failed (code: 0x%"PRIX32").\n", ret); | |
//dprintf("\t0x%04X: N/A\n", key_index); | |
break; | |
} | |
if (found) { | |
if (key_size == max_key_size - 1) { | |
*(int*)(ckd + max_key_size) = 0; | |
for (i = 0; i < max_key_size; ++i) | |
ckd[i] = current_key[max_key_size - i - 1]; | |
} | |
} else { | |
*(int*)(ckd + max_key_size) = ESRCH; | |
//dprintf("\tNOT FOUND\n"); | |
} | |
} | |
if (key_handle) { | |
ret = sceSblKeymgrClearKey(key_handle); | |
if (ret != 0) { | |
*(int*)(ckd + max_key_size) = ret; | |
//dprintf("sceSblKeymgrClearKey() failed (code: 0x%"PRIX32").\n", ret); | |
//dprintf("\t0x%04X: N/A\n", key_index); | |
break; | |
} | |
} | |
} | |
ret = 0; | |
if (key_data) { | |
*key_data = kd; | |
kd = NULL; | |
} | |
if (key_data_size) | |
*key_data_size = kds; | |
error: | |
if (d_buf) { | |
//dprintf("Unmapping data buffer from GPU...\n"); | |
sceSblDriverUnmapPages(d_buf); | |
} | |
if (buf) { | |
//dprintf("Freeing memory of data buffer...\n"); | |
dealloc(buf); | |
} | |
if (kd) { | |
//dprintf("Freeing memory of key data buffer...\n"); | |
dealloc(kd); | |
} | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great work man! Lots of ours infront of that screen.