Skip to content

Instantly share code, notes, and snippets.

@flatz
Created Dec 18, 2021
Embed
What would you like to do?
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