Merge pull request #1365 from tpunix/master

add DLC support to ppsspp
This commit is contained in:
Henrik Rydgård 2013-04-19 23:45:18 -07:00
commit d595a5d567
6 changed files with 96 additions and 35 deletions

View File

@ -471,4 +471,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -6,4 +6,4 @@ void Register_sceFont();
void __FontInit();
void __FontShutdown();
void __FontDoState(PointerWrap &p);
void __FontDoState(PointerWrap &p);

View File

@ -186,6 +186,7 @@ public:
u32 openMode;
u32 npdrm;
u32 pgd_offset;
PGD_DESC *pgdInfo;
};
@ -735,6 +736,7 @@ FileNode *__IoOpen(const char* filename, int flags, int mode) {
f->openMode = access;
f->npdrm = (flags & O_NPDRM)? true: false;
f->pgd_offset = 0;
return f;
}
@ -1365,33 +1367,54 @@ int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 out
switch (cmd) {
// Define decryption key (amctrl.prx DRM)
case 0x04100001:
case 0x04100001: {
u8 keybuf[16];
u8 *key_ptr;
u8 pgd_header[0x90];
u8 pgd_magic[4] = {0x00, 0x50, 0x47, 0x44};
if (Memory::IsValidAddress(indataPtr) && inlen == 16) {
u8 keybuf[16];
u8 pgd_header[0x90];
u8 pgd_magic[4] = {0x00, 0x50, 0x47, 0x44};
INFO_LOG(HLE, "Decrypting PGD DRM files");
memcpy(keybuf, Memory::GetPointer(indataPtr), 16);
pspFileSystem.ReadFile(f->handle, pgd_header, 0x90);
f->pgdInfo = pgd_open(pgd_header, 2, keybuf);
if(f->pgdInfo==NULL){
ERROR_LOG(HLE, "Not a valid PGD file. Open as normal file.");
f->npdrm = false;
pspFileSystem.SeekFile(f->handle, (s32)0, FILEMOVE_BEGIN);
if(memcmp(pgd_header, pgd_magic, 4)==0){
// File is PGD file, but key mismatch
return ERROR_PGD_INVALID_HEADER;
}else{
// File is decrypted.
return 0;
}
key_ptr = keybuf;
}else{
key_ptr = NULL;
}
INFO_LOG(HLE, "Decrypting PGD DRM files");
pspFileSystem.SeekFile(f->handle, (s32)f->pgd_offset, FILEMOVE_BEGIN);
pspFileSystem.ReadFile(f->handle, pgd_header, 0x90);
f->pgdInfo = pgd_open(pgd_header, 2, key_ptr);
if(f->pgdInfo==NULL){
ERROR_LOG(HLE, "Not a valid PGD file. Open as normal file.");
f->npdrm = false;
pspFileSystem.SeekFile(f->handle, (s32)0, FILEMOVE_BEGIN);
if(memcmp(pgd_header, pgd_magic, 4)==0){
// File is PGD file, but key mismatch
return ERROR_PGD_INVALID_HEADER;
}else{
// Everthing OK.
f->npdrm = true;
// File is decrypted.
return 0;
}
}else{
// Everthing OK.
f->npdrm = true;
f->pgdInfo->data_offset += f->pgd_offset;
return 0;
}
break;
}
// Set PGD offset. Called from sceNpDrmEdataSetupKey
case 0x04100002:
f->pgd_offset = indataPtr;
break;
// Get PGD data size. Called from sceNpDrmEdataGetDataSize
case 0x04100010:
if(f->pgdInfo)
return f->pgdInfo->data_size;
else
return (int)f->info.size;
break;
// Get UMD sector size
case 0x01020003:
@ -1443,7 +1466,7 @@ u32 sceIoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 ou
{
int result = __IoIoctl(id, cmd, indataPtr, inlen, outdataPtr, outlen);
// Just a low estimate on timing.
return hleDelayResult(0, "io ctrl command", 100);
return hleDelayResult(result, "io ctrl command", 100);
}
u32 sceIoIoctlAsync(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen)

View File

@ -2,34 +2,39 @@
#include "HLE.h"
u32 sceIoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen);
int sceNpDrmSetLicenseeKey(u32 npDrmKeyAddr)
{
ERROR_LOG(HLE, "UNIMPL sceNpDrmSetLicenseeKey(%08x)", npDrmKeyAddr);
INFO_LOG(HLE, "call sceNpDrmSetLicenseeKey(%08x)", npDrmKeyAddr);
return 0;
}
int sceNpDrmClearLicenseeKey()
{
ERROR_LOG(HLE, "UNIMPL sceNpDrmClearLicenseeKey()");
INFO_LOG(HLE, "call sceNpDrmClearLicenseeKey()");
return 0;
}
int sceNpDrmRenameCheck(const char *filename)
{
ERROR_LOG(HLE, "UNIMPL sceNpDrmRenameCheck(%s)", filename);
INFO_LOG(HLE, "call sceNpDrmRenameCheck(%s)", filename);
return 0;
}
int sceNpDrmEdataSetupKey(u32 edataFd)
{
ERROR_LOG(HLE, "UNIMPL sceNpDrmEdataSetupKey %x", edataFd);
return 0;
INFO_LOG(HLE, "call sceNpDrmEdataSetupKey %x", edataFd);
/* set PGD offset */
sceIoIoctl(edataFd, 0x04100002, 0x90, 0, 0, 0);
/* call PGD open */
return sceIoIoctl(edataFd, 0x04100001, 0, 0, 0, 0);
}
int sceNpDrmEdataGetDataSize(u32 edataFd)
{
ERROR_LOG(HLE, "UNIMPL sceNpDrmEdataGetDataSize %x", edataFd);
return 0;
INFO_LOG(HLE, "call sceNpDrmEdataGetDataSize %x", edataFd);
return sceIoIoctl(edataFd, 0x04100010, 0, 0, 0, 0);
}
int sceNpDrmOpen()
@ -67,4 +72,4 @@ void Register_sceNpDrm()
RegisterModule("sceNpDrm", ARRAY_SIZE(sceNpDrm), sceNpDrm);
RegisterModule("scePspNpDrm_user", ARRAY_SIZE(sceNpDrm), sceNpDrm);
}

View File

@ -334,6 +334,40 @@ int sceDrmBBMacFinal2(MAC_KEY *mkey, u8 *out, u8 *vkey)
return retv;
}
// get key from bbmac
int bbmac_getkey(MAC_KEY *mkey, u8 *bbmac, u8 *vkey)
{
int i, retv, type, code;
u8 *kbuf, tmp[16], tmp1[16];
type = mkey->type;
retv = sceDrmBBMacFinal(mkey, tmp, NULL);
if(retv)
return retv;
kbuf = kirk_buf+0x14;
// decrypt bbmac
if(type==3){
memcpy(kbuf, bbmac, 0x10);
kirk7(kirk_buf, 0x10, 0x63);
}else{
memcpy(kirk_buf, bbmac, 0x10);
}
memcpy(tmp1, kirk_buf, 16);
memcpy(kbuf, tmp1, 16);
code = (type==2)? 0x3A : 0x38;
kirk7(kirk_buf, 0x10, code);
for(i=0; i<0x10; i++){
vkey[i] = tmp[i] ^ kirk_buf[i];
}
return 0;
}
/*************************************************************/
static int sub_1F8(u8 *buf, int size, u8 *key, int key_type)
@ -625,12 +659,10 @@ PGD_DESC *pgd_open(u8 *pgd_buf, int pgd_flag, u8 *pgd_vkey)
memcpy(pgd->vkey, pgd_vkey, 16);
}
}else{
//ERROR_LOG(HLE, "pgd_open: need key!\n");
free(pgd);
return NULL;
// get vkey from MAC_70
bbmac_getkey(&mkey, pgd_buf+0x70, pgd->vkey);
}
// decrypt PGD_DESC
sceDrmBBCipherInit(&ckey, pgd->cipher_type, 2, pgd_buf+0x10, pgd->vkey, 0);
sceDrmBBCipherUpdate(&ckey, pgd_buf+0x30, 0x30);

View File

@ -45,6 +45,7 @@ int sceDrmBBMacInit(MAC_KEY *mkey, int type);
int sceDrmBBMacUpdate(MAC_KEY *mkey, u8 *buf, int size);
int sceDrmBBMacFinal(MAC_KEY *mkey, u8 *buf, u8 *vkey);
int sceDrmBBMacFinal2(MAC_KEY *mkey, u8 *out, u8 *vkey);
int bbmac_getkey(MAC_KEY *mkey, u8 *bbmac, u8 *vkey);
// type: 1 use fixed key
// 2 use fuse id