Skip to content

Instantly share code, notes, and snippets.

@flatz
Created December 18, 2021 16:28
Show Gist options
  • Star 44 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save flatz/22215327864d7512e52268f9c9c51cd8 to your computer and use it in GitHub Desktop.
Save flatz/22215327864d7512e52268f9c9c51cd8 to your computer and use it in GitHub Desktop.
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;
}
@lg4eva666
Copy link

Great work man! Lots of ours infront of that screen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment