mirror of
https://github.com/libretro/ppsspp.git
synced 2025-01-27 03:35:14 +00:00
commit
d595a5d567
@ -471,4 +471,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
@ -6,4 +6,4 @@ void Register_sceFont();
|
||||
|
||||
void __FontInit();
|
||||
void __FontShutdown();
|
||||
void __FontDoState(PointerWrap &p);
|
||||
void __FontDoState(PointerWrap &p);
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user