int sce_remove_npdrm(u8 *ptr, struct keylist *klist) { u64 ctrl_offset; u64 ctrl_size; u32 block_type; u32 block_size; u32 license_type; char content_id[0x31] = {'\0'}; struct rif *rif; struct actdat *actdat; u8 enc_const[0x10]; u8 dec_actdat[0x10]; struct key klicensee; u64 i; ctrl_offset = be64(ptr + 0x58); ctrl_size = be64(ptr + 0x60); for (i = 0; i < ctrl_size; ) { block_type = be32(ptr + ctrl_offset + i); block_size = be32(ptr + ctrl_offset + i + 0x4); if (block_type == 3) { license_type = be32(ptr + ctrl_offset + i + 0x18); switch (license_type) { case 1: // cant decrypt network stuff return -1; case 2: memcpy(content_id, ptr + ctrl_offset + i + 0x20, 0x30); rif = rif_get(content_id); if (rif == NULL) { return -1; } aes128(klist->rif->key, rif->padding, rif->padding); aes128_enc(klist->idps->key, klist->npdrm_const->key, enc_const); actdat = actdat_get(); if (actdat == NULL) { return -1; } aes128(enc_const, &actdat->keyTable[swap32(rif->actDatIndex)*0x10], dec_actdat); aes128(dec_actdat, rif->key, klicensee.key); sce_decrypt_npdrm(ptr, klist, &klicensee); return 1; case 3: sce_decrypt_npdrm(ptr, klist, klist->free_klicensee); return 1; } } i += block_size; } return 0; }
static int remove_npdrm(SELF *self, CONTROL_INFO *control_info, uint8_t *metadata, struct keylist *klist) { CONTROL_INFO *info; u32 license_type; char content_id[0x31] = {'\0'}; struct rif *rif; struct actdat *actdat; u8 enc_const[0x10]; u8 dec_actdat[0x10]; u8 klicensee[0x10]; int i; u64 off; for (i = off = 0; off < self->controlinfo_size; i++) { info = &control_info[i]; if (info->type == 3) { license_type = info->npdrm.license_type; switch (license_type) { case 1: // cant decrypt network stuff return -1; case 2: memcpy(content_id, info->npdrm.content_id, 0x30); rif = rif_get(content_id); if (rif == NULL) { return -1; } aes128(klist->rif, rif->padding, rif->padding); aes128_enc(klist->idps, klist->npdrm_const, enc_const); actdat = actdat_get(); if (actdat == NULL) { return -1; } aes128(enc_const, &actdat->keyTable[swap32(rif->actDatIndex)*0x10], dec_actdat); aes128(dec_actdat, rif->key, klicensee); decrypt_npdrm(metadata, klist, klicensee); return 1; case 3: decrypt_npdrm(metadata, klist, klist->free_klicensee); return 1; } } off += info->size; } return 0; }