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; }
static void decrypt_npdrm(uint8_t *metadata, struct keylist *klist, struct key *klicensee) { struct key d_klic; // iv is 0 memset(&d_klic, 0, sizeof(struct key)); aes128(klist->klic->key, klicensee->key, d_klic.key); aes128cbc(d_klic.key, d_klic.iv, metadata, 0x40, metadata); }
static void decrypt_npdrm(uint8_t *metadata, struct keylist *klist, u8 *klicensee) { u8 d_klic[0x10]; u8 iv[0x10]; aes128(klist->klic, klicensee, d_klic); // iv is 0 memset(iv, 0, sizeof iv); aes128cbc(d_klic, iv, metadata, 0x40, metadata); }
void sce_decrypt_npdrm(u8 *ptr, struct keylist *klist, struct key *klicensee) { u32 meta_offset; struct key d_klic; meta_offset = be32(ptr + 0x0c); // iv is 0 memset(&d_klic, 0, sizeof(struct key)); aes128(klist->klic->key, klicensee->key, d_klic.key); aes128cbc(d_klic.key, d_klic.iv, ptr + meta_offset + 0x20, 0x40, ptr + meta_offset + 0x20); }
void sce_encrypt_npdrm(u8 *ptr, struct keylist *klist, u8 *klicensee) { u32 meta_offset; u8 d_klic[0x10]; u8 iv[0x10]; meta_offset = be32(ptr + 0x0c); aes128(klist->klic, klicensee, d_klic); // iv is 0 memset(iv, 0, sizeof iv); aes128cbc_enc(d_klic, iv, ptr + meta_offset + 0x20, 0x40, ptr + meta_offset + 0x20); }
TEST(CipherCryptoAPI, AES) { CipherCryptoAPI aes128(CryptoAPICiphers::AES_CBC_128); CipherCryptoAPI aes192(CryptoAPICiphers::AES_CBC_192); CipherCryptoAPI aes256(CryptoAPICiphers::AES_CBC_256); _testKeyChange(&aes128); _testKeyChange(&aes192); _testKeyChange(&aes256); _testEnDeCrypt(&aes128, &aes128); _testEnDeCrypt(&aes192, &aes192); _testEnDeCrypt(&aes256, &aes256); }
TEST(CipherOpenSSL, AES) { CipherOpenSSL aes128(OpenSSLCiphers::AES_CBC_128); CipherOpenSSL aes192(OpenSSLCiphers::AES_CBC_192); CipherOpenSSL aes256(OpenSSLCiphers::AES_CBC_256); _testKeyChange(&aes128); _testKeyChange(&aes192); _testKeyChange(&aes256); _testEnDeCrypt(&aes128, &aes128); _testEnDeCrypt(&aes192, &aes192); _testEnDeCrypt(&aes256, &aes256); }