public PGD() { amctrl = new AMCTRL(); }
public byte[] GetKeyFromBBMac(BBMac_Ctx ctx, byte[] bbmac) { byte[] key = new byte[0x10]; byte[] decKey = new byte[0x10]; byte[] macKey = new byte[0x10]; byte[] finalKey = new byte[0x10]; int mode = ctx.mode; // This will be reset to 0 by hleDrmBBMacFinal hleDrmBBMacFinal(ctx, macKey, null); if ((mode & 0x3) == 0x3) { decKey = DecryptBBMacKey(bbmac, 0x63); } else { System.arraycopy(bbmac, 0, decKey, 0, 0x10); } int seed = getModeSeed(mode); finalKey = DecryptBBMacKey(decKey, seed); key = xorKey(macKey, 0, finalKey, 0, 0x10); return key; } }
public byte[] DecryptBBMacKey(byte[] key, int seed) { byte[] scrambleBuf = new byte[0x10 + 0x14]; byte[] decKey = new byte[0x10]; System.arraycopy(key, 0, scrambleBuf, 0x14, 0x10); ScrambleBB(scrambleBuf, 0x10, seed, 0x5, KIRK.PSP_KIRK_CMD_DECRYPT); System.arraycopy(scrambleBuf, 0, decKey, 0, 0x10); return decKey; }
public int hleDrmBBMacFinal2(BBMac_Ctx ctx, byte[] hash, byte[] key) { byte[] resBuf = new byte[0x10]; byte[] hashBuf = new byte[0x10]; int mode = ctx.mode; // Call hleDrmBBMacFinal on an empty buffer. hleDrmBBMacFinal(ctx, resBuf, key); // If mode is 3, decrypt the hash first. if ((mode & 0x3) == 0x3) { hashBuf = DecryptBBMacKey(hash, 0x63); } else { hashBuf = hash; } // Compare the hashes. for (int i = 0; i < 0x10; i++) { if (hashBuf[i] != resBuf[i]) { return -1; } } return 0; }
amctrl.hleDrmBBMacInit(macContext, 3); amctrl.hleDrmBBMacUpdate(macContext, header, 0xC0); byte[] macKeyC0 = new byte[16]; System.arraycopy(header, 0xC0, macKeyC0, 0, macKeyC0.length); vkey = amctrl.GetKeyFromBBMac(macContext, macKeyC0); System.arraycopy(header, 0x40, cipherData, 0, cipherData.length); System.arraycopy(header, 0xA0, hkey, 0, hkey.length); amctrl.hleDrmBBCipherInit(cipherContext, 1, 2, hkey, vkey); amctrl.hleDrmBBCipherUpdate(cipherContext, cipherData, cipherData.length); amctrl.hleDrmBBCipherFinal(cipherContext);
public byte[] DecryptPGD(byte[] inbuf, int size, byte[] key, int seed) { // Setup the crypto and keygen modes and initialize both context structs. int sdEncMode = 1; int sdGenMode = 2; pgdMacContext = new AMCTRL.BBMac_Ctx(); pgdCipherContext = new AMCTRL.BBCipher_Ctx(); // Align the buffers to 16-bytes. int alignedSize = ((size + 0xF) >> 4) << 4; byte[] outbuf = new byte[alignedSize - 0x10]; byte[] dataBuf = new byte[alignedSize]; // Fully copy the contents of the encrypted file. System.arraycopy(inbuf, 0, dataBuf, 0, size); amctrl.hleDrmBBMacInit(pgdMacContext, sdEncMode); amctrl.hleDrmBBCipherInit(pgdCipherContext, sdEncMode, sdGenMode, dataBuf, key, seed); amctrl.hleDrmBBMacUpdate(pgdMacContext, dataBuf, 0x10); System.arraycopy(dataBuf, 0x10, outbuf, 0, alignedSize - 0x10); amctrl.hleDrmBBMacUpdate(pgdMacContext, outbuf, alignedSize - 0x10); amctrl.hleDrmBBCipherUpdate(pgdCipherContext, outbuf, alignedSize - 0x10); return outbuf; }
amctrl.hleDrmBBMacInit(pgdMacContext, macEncMode); amctrl.hleDrmBBMacUpdate(pgdMacContext, dataBuf, 0x80); amctrl.hleDrmBBMacFinal2(pgdMacContext, macKey80, dnasKey); amctrl.hleDrmBBMacInit(pgdMacContext, macEncMode); amctrl.hleDrmBBMacUpdate(pgdMacContext, dataBuf, 0x70); return amctrl.GetKeyFromBBMac(pgdMacContext, macKey70);
header = xorHash(header, 0x14, KeyVault.amHashKey4, 0, 0x10); ScrambleBB(header, 0x10, 0x100, 0x4, KIRK.PSP_KIRK_CMD_ENCRYPT_FUSE); header = xorHash(header, 0x14, KeyVault.amHashKey5, 0, 0x10); System.arraycopy(header, 0x14, ctx.buf, 0, 0x10); System.arraycopy(header, 0x14, data, 0, 0x10); if (!isNullKey(key)) { ctx.buf = xorKey(ctx.buf, 0, key, 0, 0x10); header = xorHash(header, 0x14, KeyVault.amHashKey4, 0, 0x10); ScrambleBB(header, 0x10, 0x39, 0x4, KIRK.PSP_KIRK_CMD_ENCRYPT); header = xorHash(header, 0x14, KeyVault.amHashKey5, 0, 0x10); System.arraycopy(header, 0x14, ctx.buf, 0, 0x10); System.arraycopy(header, 0x14, data, 0, 0x10); if (!isNullKey(key)) { ctx.buf = xorKey(ctx.buf, 0, key, 0, 0x10); if (!isNullKey(key)) { ctx.buf = xorKey(ctx.buf, 0, key, 0, 0x10);
int seed = getModeSeed(ctx.mode); ScrambleBB(scrambleBuf, 0x10, seed, 0x4, KIRK.PSP_KIRK_CMD_ENCRYPT); ctx.pad = xorKey(ctx.pad, 0, keyBuf, 0, 0x10); System.arraycopy(ctx.pad, 0, scrambleBuf, 0x14, 0x10); scrambleBuf = xorKey(scrambleBuf, 0x14, resultBuf, 0, 0x10); ScrambleBB(scrambleBuf, 0x10, seed, 0x4, KIRK.PSP_KIRK_CMD_ENCRYPT); resultBuf = xorHash(resultBuf, 0, KeyVault.amHashKey3, 0, 0x10); ScrambleBB(scrambleBuf, 0x10, 0x100, 0x4, KIRK.PSP_KIRK_CMD_ENCRYPT_FUSE); ScrambleBB(scrambleBuf, 0x10, seed, 0x4, KIRK.PSP_KIRK_CMD_ENCRYPT); resultBuf = xorKey(resultBuf, 0, key, 0, 0x10); ScrambleBB(scrambleBuf, 0x10, seed, 0x4, KIRK.PSP_KIRK_CMD_ENCRYPT);
dataBuf = xorHash(dataBuf, 0x14, KeyVault.amHashKey5, 0, 0x10); ScrambleBB(dataBuf, 0x10, 0x100, 5, KIRK.PSP_KIRK_CMD_DECRYPT_FUSE); dataBuf = xorHash(dataBuf, 0, KeyVault.amHashKey4, 0, 0x10); } else { dataBuf = xorHash(dataBuf, 0x14, KeyVault.amHashKey5, 0, 0x10); ScrambleBB(dataBuf, 0x10, 0x39, 5, KIRK.PSP_KIRK_CMD_DECRYPT); dataBuf = xorHash(dataBuf, 0, KeyVault.amHashKey4, 0, 0x10); ScrambleBB(dataBuf, length, 0x63, 5, KIRK.PSP_KIRK_CMD_DECRYPT); dataBuf = xorKey(dataBuf, 0, keyBuf1, 0, 0x10); xorKey(data, data_offset, dataBuf, 0, length);
} else { int seed = getModeSeed(ctx.mode); if (nLen == blockSize) { scrambleBuf = xorKey(scrambleBuf, 0x14, ctx.key, 0, 0x10); ScrambleBB(scrambleBuf, blockSize, seed, 0x4, KIRK.PSP_KIRK_CMD_ENCRYPT); System.arraycopy(scrambleBuf, blockSize + 0x4, ctx.key, 0, 0x10); scrambleBuf = xorKey(scrambleBuf, 0x14, ctx.key, 0, 0x10); ScrambleBB(scrambleBuf, nLen, seed, 0x4, KIRK.PSP_KIRK_CMD_ENCRYPT); System.arraycopy(scrambleBuf, nLen + 0x4, ctx.key, 0, 0x10);
if ((table[block].flags & TableInfo.FLAG_IS_UNCRYPTED) == 0) { BBCipher_Ctx cipherContext = new BBCipher_Ctx(); amctrl.hleDrmBBCipherInit(cipherContext, 1, 2, hkey, vkey, table[block].offset >> 4); amctrl.hleDrmBBCipherUpdate(cipherContext, readBuffer, table[block].size); amctrl.hleDrmBBCipherFinal(cipherContext);
amctrl.hleDrmBBMacInit(bbctx, 1); amctrl.hleDrmBBMacUpdate(bbctx, data, data.length); amctrl.hleDrmBBMacFinal(bbctx, hash, fixedKey);
public int hleDrmBBCipherInit(BBCipher_Ctx ctx, int encMode, int genMode, byte[] data, byte[] key) { return hleDrmBBCipherInit(ctx, encMode, genMode, data, key, 0); }
public void FinishPGDCipher() { amctrl.hleDrmBBCipherFinal(pgdCipherContext); }
public int hleDrmBBCipherUpdate(BBCipher_Ctx ctx, byte[] data, int length) { if (length == 0) { return 0; } if ((length & 0xF) != 0) { return -1; } // Parse the data in 0x800 blocks first. int index = 0; if (length >= 0x800) { for (index = 0; length >= 0x800; index += 0x800) { cipherMember(ctx, data, index, 0x800); length -= 0x800; } } // Finally parse the rest of the data. if (length >= 0x10) { cipherMember(ctx, data, index, length); } return 0; }
public byte[] UpdatePGDCipher(byte[] inbuf, int size) { // Align the buffers to 16-bytes. int alignedSize = ((size + 0xF) >> 4) << 4; byte[] outbuf = new byte[alignedSize - 0x10]; byte[] dataBuf = new byte[alignedSize]; System.arraycopy(inbuf, 0, dataBuf, 0, size); System.arraycopy(dataBuf, 0x10, outbuf, 0, alignedSize - 0x10); amctrl.hleDrmBBCipherUpdate(pgdCipherContext, outbuf, alignedSize - 0x10); return outbuf; }
public DRM() { amctrl = new AMCTRL(); }
public CryptoEngine() { installSettingsListeners(); setCryptoEngineStatus(true); kirk = new KIRK(); prx = new PRX(); sd = new SAVEDATA(); amctrl = new AMCTRL(); pgd = new PGD(); drm = new DRM(); }