mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Remove global state from kirk engine
This commit is contained in:
@@ -1674,6 +1674,7 @@ add_library(kirk STATIC
|
||||
ext/libkirk/ec.c
|
||||
ext/libkirk/kirk_engine.c
|
||||
ext/libkirk/kirk_engine.h
|
||||
ext/libkirk/kirk_common.h
|
||||
)
|
||||
target_include_directories(kirk PRIVATE ext/libkirk)
|
||||
|
||||
|
||||
+17
-16
@@ -711,7 +711,7 @@ struct PRXType6
|
||||
};
|
||||
static_assert(sizeof(PRXType6) == 0x150, "inconsistent size of PRX Type 6");
|
||||
|
||||
static int pspDecryptType0(const u8 *inbuf, u8 *outbuf, u32 size)
|
||||
static int pspDecryptType0(KirkState *kirk, const u8 *inbuf, u8 *outbuf, u32 size)
|
||||
{
|
||||
INFO_LOG(Log::Loader, "Decrypting tag %02X", (u32)*(u32_le *)&inbuf[0xD0]);
|
||||
const auto decryptSize = *(s32_le*)&inbuf[0xB0];
|
||||
@@ -757,7 +757,7 @@ static int pspDecryptType0(const u8 *inbuf, u8 *outbuf, u32 size)
|
||||
memcpy(reinterpret_cast<u8*>(header)+sizeof(KIRK_CMD1_HEADER), type0.prxHeader, sizeof(type0.prxHeader));
|
||||
decryptKirkHeaderType0(reinterpret_cast<u8*>(header), type0.kirkBlock, xorbuf, pti->code);
|
||||
|
||||
if (kirk_sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast<u8*>(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0)
|
||||
if (kirk_sceUtilsBufferCopyWithRange(kirk, outbuf, size, reinterpret_cast<u8*>(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0)
|
||||
{
|
||||
return -4;
|
||||
}
|
||||
@@ -765,7 +765,7 @@ static int pspDecryptType0(const u8 *inbuf, u8 *outbuf, u32 size)
|
||||
return decryptSize;
|
||||
}
|
||||
|
||||
static int pspDecryptType1(const u8 *inbuf, u8 *outbuf, u32 size)
|
||||
static int pspDecryptType1(KirkState *kirk, const u8 *inbuf, u8 *outbuf, u32 size)
|
||||
{
|
||||
INFO_LOG(Log::Loader, "Decrypting tag %02X", (u32)*(u32_le *)&inbuf[0xD0]);
|
||||
const auto decryptSize = *(s32_le*)&inbuf[0xB0];
|
||||
@@ -812,7 +812,7 @@ static int pspDecryptType1(const u8 *inbuf, u8 *outbuf, u32 size)
|
||||
memcpy(reinterpret_cast<u8*>(header)+sizeof(KIRK_CMD1_HEADER), type1.prxHeader, sizeof(type1.prxHeader));
|
||||
decryptKirkHeaderType0(reinterpret_cast<u8*>(header), type1.kirkBlock, xorbuf, pti->code);
|
||||
|
||||
if (kirk_sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast<u8*>(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0)
|
||||
if (kirk_sceUtilsBufferCopyWithRange(kirk, outbuf, size, reinterpret_cast<u8*>(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0)
|
||||
{
|
||||
return -4;
|
||||
}
|
||||
@@ -820,7 +820,7 @@ static int pspDecryptType1(const u8 *inbuf, u8 *outbuf, u32 size)
|
||||
return decryptSize;
|
||||
}
|
||||
|
||||
static int pspDecryptType2(const u8 *inbuf, u8 *outbuf, u32 size)
|
||||
static int pspDecryptType2(KirkState *kirk, const u8 *inbuf, u8 *outbuf, u32 size)
|
||||
{
|
||||
INFO_LOG(Log::Loader, "Decrypting tag %02X", (u32)*(u32_le *)&inbuf[0xD0]);
|
||||
const auto decryptSize = *(s32_le*)&inbuf[0xB0];
|
||||
@@ -876,7 +876,7 @@ static int pspDecryptType2(const u8 *inbuf, u8 *outbuf, u32 size)
|
||||
decryptKirkHeader(reinterpret_cast<u8*>(header), type2.kirkHeader, xorbuf.cbegin()+0x10, pti->code);
|
||||
header->mode = 1;
|
||||
|
||||
if (kirk_sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast<u8*>(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0)
|
||||
if (kirk_sceUtilsBufferCopyWithRange(kirk, outbuf, size, reinterpret_cast<u8*>(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0)
|
||||
{
|
||||
return -4;
|
||||
}
|
||||
@@ -884,7 +884,7 @@ static int pspDecryptType2(const u8 *inbuf, u8 *outbuf, u32 size)
|
||||
return decryptSize;
|
||||
}
|
||||
|
||||
static int pspDecryptType5(const u8 *inbuf, u8 *outbuf, u32 size, const u8 *seed)
|
||||
static int pspDecryptType5(KirkState *kirk, const u8 *inbuf, u8 *outbuf, u32 size, const u8 *seed)
|
||||
{
|
||||
INFO_LOG(Log::Loader, "Decrypting tag %02X", (u32)*(u32_le *)&inbuf[0xD0]);
|
||||
const auto decryptSize = *(s32_le*)&inbuf[0xB0];
|
||||
@@ -940,7 +940,7 @@ static int pspDecryptType5(const u8 *inbuf, u8 *outbuf, u32 size, const u8 *seed
|
||||
decryptKirkHeader(reinterpret_cast<u8*>(header), type5.kirkHeader, xorbuf.cbegin()+0x10, pti->code);
|
||||
header->mode = 1;
|
||||
|
||||
if (kirk_sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast<u8*>(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0)
|
||||
if (kirk_sceUtilsBufferCopyWithRange(kirk, outbuf, size, reinterpret_cast<u8*>(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0)
|
||||
{
|
||||
return -4;
|
||||
}
|
||||
@@ -948,7 +948,7 @@ static int pspDecryptType5(const u8 *inbuf, u8 *outbuf, u32 size, const u8 *seed
|
||||
return decryptSize;
|
||||
}
|
||||
|
||||
static int pspDecryptType6(const u8 *inbuf, u8 *outbuf, u32 size)
|
||||
static int pspDecryptType6(KirkState *kirk, const u8 *inbuf, u8 *outbuf, u32 size)
|
||||
{
|
||||
INFO_LOG(Log::Loader, "Decrypting tag %02X", (u32)*(u32_le *)&inbuf[0xD0]);
|
||||
const auto decryptSize = *(s32_le*)&inbuf[0xB0];
|
||||
@@ -1007,7 +1007,7 @@ static int pspDecryptType6(const u8 *inbuf, u8 *outbuf, u32 size)
|
||||
header->mode = 1;
|
||||
header->ecdsa_hash = 1;
|
||||
|
||||
if (kirk_sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast<u8*>(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0)
|
||||
if (kirk_sceUtilsBufferCopyWithRange(kirk, outbuf, size, reinterpret_cast<u8*>(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0)
|
||||
{
|
||||
return -4;
|
||||
}
|
||||
@@ -1017,30 +1017,31 @@ static int pspDecryptType6(const u8 *inbuf, u8 *outbuf, u32 size)
|
||||
|
||||
int pspDecryptPRX(const u8 *inbuf, u8 *outbuf, u32 size, const u8 *seed)
|
||||
{
|
||||
kirk_init();
|
||||
KirkState kirk{};
|
||||
kirk_init(&kirk);
|
||||
|
||||
// this would be significantly better if we had a log of the tags
|
||||
// and their appropriate prx types
|
||||
// since we don't know the PRX type we attempt a decrypt using all
|
||||
auto res = pspDecryptType0(inbuf, outbuf, size);
|
||||
auto res = pspDecryptType0(&kirk, inbuf, outbuf, size);
|
||||
|
||||
if (res >= 0)
|
||||
return res;
|
||||
|
||||
res = pspDecryptType1(inbuf, outbuf, size);
|
||||
res = pspDecryptType1(&kirk, inbuf, outbuf, size);
|
||||
|
||||
if (res >= 0)
|
||||
return res;
|
||||
|
||||
res = pspDecryptType2(inbuf, outbuf, size);
|
||||
res = pspDecryptType2(&kirk, inbuf, outbuf, size);
|
||||
|
||||
if (res >= 0)
|
||||
return res;
|
||||
|
||||
res = pspDecryptType5(inbuf, outbuf, size, seed);
|
||||
res = pspDecryptType5(&kirk, inbuf, outbuf, size, seed);
|
||||
|
||||
if (res >= 0)
|
||||
return res;
|
||||
|
||||
return pspDecryptType6(inbuf, outbuf, size);
|
||||
return pspDecryptType6(&kirk, inbuf, outbuf, size);
|
||||
}
|
||||
|
||||
@@ -381,7 +381,6 @@ bool CISOFileBlockDevice::ReadBlocks(u32 minBlock, int count, u8 *outPtr) {
|
||||
NPDRMDemoBlockDevice::NPDRMDemoBlockDevice(FileLoader *fileLoader)
|
||||
: BlockDevice(fileLoader)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
MAC_KEY mkey;
|
||||
CIPHER_KEY ckey;
|
||||
u8 np_header[256];
|
||||
@@ -404,17 +403,20 @@ NPDRMDemoBlockDevice::NPDRMDemoBlockDevice(FileLoader *fileLoader)
|
||||
return;
|
||||
}
|
||||
|
||||
kirk_init();
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
|
||||
// Local kirk instance to not clash with other block devices and other decryption things.
|
||||
kirk_init(&kirk_);
|
||||
|
||||
// getkey
|
||||
sceDrmBBMacInit(&mkey, 3);
|
||||
sceDrmBBMacUpdate(&mkey, np_header, 0xc0);
|
||||
bbmac_getkey(&mkey, np_header+0xc0, vkey);
|
||||
sceDrmBBMacUpdate(&kirk_, &mkey, np_header, 0xc0);
|
||||
bbmac_getkey(&kirk_, &mkey, np_header+0xc0, vkey);
|
||||
|
||||
// decrypt NP header
|
||||
memcpy(hkey, np_header+0xa0, 0x10);
|
||||
sceDrmBBCipherInit(&ckey, 1, 2, hkey, vkey, 0);
|
||||
sceDrmBBCipherUpdate(&ckey, np_header+0x40, 0x60);
|
||||
sceDrmBBCipherInit(&kirk_, &ckey, 1, 2, hkey, vkey, 0);
|
||||
sceDrmBBCipherUpdate(&kirk_, &ckey, np_header+0x40, 0x60);
|
||||
sceDrmBBCipherFinal(&ckey);
|
||||
|
||||
u32 lbaStart = *(u32*)(np_header+0x54); // LBA start
|
||||
@@ -523,8 +525,8 @@ bool NPDRMDemoBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached)
|
||||
|
||||
if ((table_[block].flag & 4) == 0) {
|
||||
CIPHER_KEY ckey;
|
||||
sceDrmBBCipherInit(&ckey, 1, 2, hkey, vkey, table_[block].offset>>4);
|
||||
sceDrmBBCipherUpdate(&ckey, readBuf, table_[block].size);
|
||||
sceDrmBBCipherInit(&kirk_, &ckey, 1, 2, hkey, vkey, table_[block].offset>>4);
|
||||
sceDrmBBCipherUpdate(&kirk_, &ckey, readBuf, table_[block].size);
|
||||
sceDrmBBCipherFinal(&ckey);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
#include "ext/libkirk/kirk_engine.h"
|
||||
|
||||
class FileLoader;
|
||||
|
||||
class BlockDevice {
|
||||
@@ -117,7 +119,7 @@ public:
|
||||
bool IsDisc() const override { return false; }
|
||||
|
||||
private:
|
||||
// TODO: Doubt this mutex is actually needed.
|
||||
// This is in case two threads hit this same block device, which shouldn't really happen.
|
||||
std::mutex mutex_;
|
||||
|
||||
u32 lbaSize_ = 0;
|
||||
@@ -134,6 +136,10 @@ private:
|
||||
int currentBlock_ = 0;
|
||||
u8 *blockBuf_ = nullptr;
|
||||
u8 *tempBuf_ = nullptr;
|
||||
|
||||
// Each block device gets its own private kirk. Multiple ones can be in flight
|
||||
// to load metadata.
|
||||
KirkState kirk_{};
|
||||
};
|
||||
|
||||
struct CHDImpl;
|
||||
|
||||
+64
-32
@@ -21,13 +21,15 @@
|
||||
|
||||
#include "Core/HLE/sceChnnlsv.h"
|
||||
#include "Core/HLE/sceKernel.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "ext/libkirk/kirk_engine.h"
|
||||
|
||||
static KirkState g_kirk;
|
||||
|
||||
KirkState *__ChnnlsvKirkState() {
|
||||
return &g_kirk;
|
||||
}
|
||||
|
||||
u8 dataBuf[2048+20];
|
||||
u8* dataBuf2 = dataBuf + 20;
|
||||
static u8 dataBuf[2048+20];
|
||||
static u8 *dataBuf2 = dataBuf + 20;
|
||||
|
||||
static const u8 hash198C[16] = {0xFA, 0xAA, 0x50, 0xEC, 0x2F, 0xDE, 0x54, 0x93, 0xAD, 0x14, 0xB2, 0xCE, 0xA5, 0x30, 0x05, 0xDF};
|
||||
static const u8 hash19BC[16] = {0xCB, 0x15, 0xF4, 0x07, 0xF9, 0x6A, 0x52, 0x3C, 0x04, 0xB9, 0xB2, 0xEE, 0x5C, 0x53, 0xFA, 0x86};
|
||||
@@ -91,7 +93,7 @@ static int typeFromMode(int mode)
|
||||
((mode == 3 || mode == 4) ? 87 : 100);
|
||||
}
|
||||
|
||||
static int kirkSendCmd(u8* data, int length, int num, bool encrypt)
|
||||
static int kirkSendCmd(KirkState *kirk, u8* data, int length, int num, bool encrypt)
|
||||
{
|
||||
*(int*)(data+0) = encrypt ? KIRK_MODE_ENCRYPT_CBC : KIRK_MODE_DECRYPT_CBC;
|
||||
*(int*)(data+4) = 0;
|
||||
@@ -99,13 +101,13 @@ static int kirkSendCmd(u8* data, int length, int num, bool encrypt)
|
||||
*(int*)(data+12) = num;
|
||||
*(int*)(data+16) = length;
|
||||
|
||||
if (kirk_sceUtilsBufferCopyWithRange(data, length + 20, data, length + 20, encrypt ? KIRK_CMD_ENCRYPT_IV_0 : KIRK_CMD_DECRYPT_IV_0))
|
||||
if (kirk_sceUtilsBufferCopyWithRange(kirk, data, length + 20, data, length + 20, encrypt ? KIRK_CMD_ENCRYPT_IV_0 : KIRK_CMD_DECRYPT_IV_0))
|
||||
return -257;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kirkSendFuseCmd(u8* data, int length, bool encrypt)
|
||||
static int kirkSendFuseCmd(KirkState *kirk, u8* data, int length, bool encrypt)
|
||||
{
|
||||
*(int*)(data+0) = encrypt ? KIRK_MODE_ENCRYPT_CBC : KIRK_MODE_DECRYPT_CBC;
|
||||
*(int*)(data+4) = 0;
|
||||
@@ -114,18 +116,18 @@ static int kirkSendFuseCmd(u8* data, int length, bool encrypt)
|
||||
*(int*)(data+16) = length;
|
||||
|
||||
// Note: CMD 5 and 8 are not available, will always return -1
|
||||
if (kirk_sceUtilsBufferCopyWithRange(data, length + 20, data, length + 20, encrypt ? KIRK_CMD_ENCRYPT_IV_FUSE : KIRK_CMD_DECRYPT_IV_FUSE))
|
||||
if (kirk_sceUtilsBufferCopyWithRange(kirk, data, length + 20, data, length + 20, encrypt ? KIRK_CMD_ENCRYPT_IV_FUSE : KIRK_CMD_DECRYPT_IV_FUSE))
|
||||
return -258;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sub_15B0(u8* data, int alignedLen, u8* buf, int val)
|
||||
static int sub_15B0(KirkState *kirk, u8* data, int alignedLen, u8* buf, int val)
|
||||
{
|
||||
u8 sp0[16];
|
||||
memcpy(sp0, data+alignedLen+4, 16);
|
||||
|
||||
int res = kirkSendCmd(data, alignedLen, val, false);
|
||||
int res = kirkSendCmd(kirk, data, alignedLen, val, false);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
@@ -134,7 +136,7 @@ static int sub_15B0(u8* data, int alignedLen, u8* buf, int val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sub_0000(u8* data_out, u8* data, int alignedLen, const u8* data2, int& data3, int mode)
|
||||
static int sub_0000(KirkState *kirk, u8* data_out, u8* data, int alignedLen, const u8* data2, int& data3, int mode)
|
||||
{
|
||||
memcpy(data_out+20, data2, 16);
|
||||
// Mode 1:2 is 83, 3:4 is 87, 5:6 is 100
|
||||
@@ -149,9 +151,9 @@ static int sub_0000(u8* data_out, u8* data, int alignedLen, const u8* data2, int
|
||||
// Odd is Cmd, Even is FuseCmd
|
||||
switch(mode)
|
||||
{
|
||||
case 2: case 4: case 6: res = kirkSendFuseCmd(data_out, 16, false);
|
||||
case 2: case 4: case 6: res = kirkSendFuseCmd(kirk, data_out, 16, false);
|
||||
break;
|
||||
case 1: case 3: default:res = kirkSendCmd(data_out, 16, numFromMode2(mode), false);
|
||||
case 1: case 3: default:res = kirkSendCmd(kirk, data_out, 16, numFromMode2(mode), false);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -185,7 +187,7 @@ static int sub_0000(u8* data_out, u8* data, int alignedLen, const u8* data2, int
|
||||
}
|
||||
}
|
||||
|
||||
res = sub_15B0(data_out, alignedLen, sp0, type);
|
||||
res = sub_15B0(kirk, data_out, alignedLen, sp0, type);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
@@ -195,11 +197,11 @@ static int sub_0000(u8* data_out, u8* data, int alignedLen, const u8* data2, int
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sub_1510(u8* data, int size, u8* result , int num)
|
||||
static int sub_1510(KirkState *kirk, u8* data, int size, u8* result , int num)
|
||||
{
|
||||
memxor(data+20, result, 16);
|
||||
|
||||
int res = kirkSendCmd(data, size, num, true);
|
||||
int res = kirkSendCmd(kirk, data, size, num, true);
|
||||
if(res)
|
||||
return res;
|
||||
|
||||
@@ -207,9 +209,9 @@ static int sub_1510(u8* data, int size, u8* result , int num)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sub_17A8(u8* data)
|
||||
static int sub_17A8(KirkState *kirk, u8* data)
|
||||
{
|
||||
if (kirk_sceUtilsBufferCopyWithRange(data, 20, 0, 0, 14) == 0)
|
||||
if (kirk_sceUtilsBufferCopyWithRange(kirk, data, 20, 0, 0, 14) == 0)
|
||||
return 0;
|
||||
return -261;
|
||||
}
|
||||
@@ -231,7 +233,7 @@ int sceSdMacFinal(pspChnnlsvContext1& ctx, u8* in_hash, const u8* in_key)
|
||||
|
||||
memset(dataBuf2, 0, 16);
|
||||
|
||||
int res = kirkSendCmd(dataBuf, 16, num, true);
|
||||
int res = kirkSendCmd(&g_kirk, dataBuf, 16, num, true);
|
||||
if(res)
|
||||
return res;
|
||||
|
||||
@@ -279,7 +281,7 @@ int sceSdMacFinal(pspChnnlsvContext1& ctx, u8* in_hash, const u8* in_key)
|
||||
memcpy(dataBuf2, ctx.key, 16);
|
||||
memcpy(data2, ctx.result, 16);
|
||||
|
||||
int ret = sub_1510(dataBuf, 16, data2, num);
|
||||
int ret = sub_1510(&g_kirk, dataBuf, 16, data2, num);
|
||||
if(ret)
|
||||
return ret;
|
||||
|
||||
@@ -292,11 +294,11 @@ int sceSdMacFinal(pspChnnlsvContext1& ctx, u8* in_hash, const u8* in_key)
|
||||
if(cond != 0)
|
||||
{
|
||||
memcpy(dataBuf2, data2, 16);
|
||||
int ret = kirkSendFuseCmd(dataBuf, 16, true);
|
||||
int ret = kirkSendFuseCmd(&g_kirk, dataBuf, 16, true);
|
||||
if(ret)
|
||||
return ret;
|
||||
|
||||
int res = kirkSendCmd(dataBuf, 16, num, true);
|
||||
int res = kirkSendCmd(&g_kirk, dataBuf, 16, num, true);
|
||||
if(res)
|
||||
return res;
|
||||
|
||||
@@ -312,7 +314,7 @@ int sceSdMacFinal(pspChnnlsvContext1& ctx, u8* in_hash, const u8* in_key)
|
||||
|
||||
memcpy(dataBuf2, data2, 16);
|
||||
|
||||
int res = kirkSendCmd(dataBuf, 16, num, true);
|
||||
int res = kirkSendCmd(&g_kirk, dataBuf, 16, num, true);
|
||||
if(res)
|
||||
return res;
|
||||
|
||||
@@ -376,7 +378,7 @@ int sceSdMacUpdate(pspChnnlsvContext1& ctx, const u8* data, int length)
|
||||
{
|
||||
if(newSize == 2048)
|
||||
{
|
||||
int res = sub_1510(dataBuf, 2048, ctx.result, num);
|
||||
int res = sub_1510(&g_kirk, dataBuf, 2048, ctx.result, num);
|
||||
if(res)
|
||||
return res;
|
||||
newSize = 0;
|
||||
@@ -385,7 +387,7 @@ int sceSdMacUpdate(pspChnnlsvContext1& ctx, const u8* data, int length)
|
||||
newSize++;
|
||||
}
|
||||
if(newSize)
|
||||
sub_1510(dataBuf, newSize, ctx.result, num);
|
||||
sub_1510(&g_kirk, dataBuf, newSize, ctx.result, num);
|
||||
// The RE code showed this always returning 0. I suspect it would want to return res instead.
|
||||
return 0;
|
||||
}
|
||||
@@ -416,7 +418,7 @@ int sceSdCipherInit(pspChnnlsvContext2& ctx2, int mode, int uknw, u8* data, cons
|
||||
{
|
||||
u8 kirkHeader[37];
|
||||
u8* kirkData = kirkHeader+20;
|
||||
int res = sub_17A8(kirkHeader);
|
||||
int res = sub_17A8(&g_kirk, kirkHeader);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
@@ -431,9 +433,9 @@ int sceSdCipherInit(pspChnnlsvContext2& ctx2, int mode, int uknw, u8* data, cons
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 2: case 4: case 6: res = kirkSendFuseCmd(kirkHeader, 16, true);
|
||||
case 2: case 4: case 6: res = kirkSendFuseCmd(&g_kirk, kirkHeader, 16, true);
|
||||
break;
|
||||
case 1: case 3: default:res = kirkSendCmd(kirkHeader, 16, numFromMode2(mode), true);
|
||||
case 1: case 3: default:res = kirkSendCmd(&g_kirk, kirkHeader, 16, numFromMode2(mode), true);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -480,7 +482,7 @@ int sceSdCipherUpdate(pspChnnlsvContext2& ctx, u8* data, int alignedLen)
|
||||
for(i = 0; alignedLen >= 2048; i += 2048)
|
||||
{
|
||||
int ctx_unkn = ctx.unkn;
|
||||
int res = sub_0000(kirkData, data + i, 2048, ctx.cryptedData, ctx_unkn, ctx.mode);
|
||||
int res = sub_0000(&g_kirk, kirkData, data + i, 2048, ctx.cryptedData, ctx_unkn, ctx.mode);
|
||||
ctx.unkn = ctx_unkn;
|
||||
alignedLen -= 2048;
|
||||
if (res)
|
||||
@@ -492,7 +494,7 @@ int sceSdCipherUpdate(pspChnnlsvContext2& ctx, u8* data, int alignedLen)
|
||||
return 0;
|
||||
}
|
||||
int ctx_unkn = ctx.unkn;
|
||||
int res = sub_0000(kirkData, data + i, alignedLen, ctx.cryptedData, ctx_unkn, ctx.mode);
|
||||
int res = sub_0000(&g_kirk, kirkData, data + i, alignedLen, ctx.cryptedData, ctx_unkn, ctx.mode);
|
||||
ctx.unkn = ctx_unkn;
|
||||
return res;
|
||||
}
|
||||
@@ -526,5 +528,35 @@ const HLEFunction sceChnnlsv[] =
|
||||
void Register_sceChnnlsv()
|
||||
{
|
||||
RegisterHLEModule("sceChnnlsv", ARRAY_SIZE(sceChnnlsv), sceChnnlsv);
|
||||
kirk_init();
|
||||
kirk_init(&g_kirk);
|
||||
}
|
||||
|
||||
// The below functions don't really belong to sceKernelSemaphore. They are the core crypto functionality,
|
||||
// exposed through the confusingly named "sceUtilsBufferCopyWithRange" name, which Sony placed in the
|
||||
// not-at-all-suspicious "semaphore" library, which has nothing to do with semaphores.
|
||||
|
||||
static u32 sceUtilsBufferCopyWithRange(u32 outAddr, int outSize, u32 inAddr, int inSize, int cmd) {
|
||||
u8 *outAddress = Memory::IsValidRange(outAddr, outSize) ? Memory::GetPointerWriteUnchecked(outAddr) : nullptr;
|
||||
u8 *inAddress = Memory::IsValidRange(inAddr, inSize) ? Memory::GetPointerWriteUnchecked(inAddr) : nullptr;
|
||||
int temp = kirk_sceUtilsBufferCopyWithRange(&g_kirk, outAddress, outSize, inAddress, inSize, cmd);
|
||||
if (temp != 0) {
|
||||
ERROR_LOG(Log::sceKernel, "hleUtilsBufferCopyWithRange: Failed with %d", temp);
|
||||
}
|
||||
return hleNoLog(0);
|
||||
}
|
||||
|
||||
// Note sure what difference there is between this and sceUtilsBufferCopyWithRange.
|
||||
static int sceUtilsBufferCopyByPollingWithRange(u32 outAddr, int outSize, u32 inAddr, int inSize, int cmd) {
|
||||
u8 *outAddress = Memory::IsValidRange(outAddr, outSize) ? Memory::GetPointerWriteUnchecked(outAddr) : nullptr;
|
||||
u8 *inAddress = Memory::IsValidRange(inAddr, inSize) ? Memory::GetPointerWriteUnchecked(inAddr) : nullptr;
|
||||
return hleNoLog(kirk_sceUtilsBufferCopyWithRange(&g_kirk, outAddress, outSize, inAddress, inSize, cmd));
|
||||
}
|
||||
|
||||
const HLEFunction semaphore[] = {
|
||||
{0x4C537C72, &WrapU_UIUII<sceUtilsBufferCopyWithRange>, "sceUtilsBufferCopyWithRange", 'x', "xixii" },
|
||||
{0x77E97079, &WrapI_UIUII<sceUtilsBufferCopyByPollingWithRange>, "sceUtilsBufferCopyByPollingWithRange", 'i', "xixii" },
|
||||
};
|
||||
|
||||
void Register_semaphore() {
|
||||
RegisterHLEModule("semaphore", ARRAY_SIZE(semaphore), semaphore);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ext/libkirk/kirk_engine.h"
|
||||
|
||||
typedef struct _pspChnnlsvContext1 {
|
||||
/** Cipher mode */
|
||||
s32_le mode;
|
||||
@@ -41,4 +43,8 @@ int sceSdCipherUpdate(pspChnnlsvContext2& ctx, u8* data, int alignedLen);
|
||||
int sceSdCipherFinal(pspChnnlsvContext2& ctx);
|
||||
int sceSdMacFinal(pspChnnlsvContext1& ctx, u8* in_hash, const u8* in_key);
|
||||
|
||||
KirkState *__ChnnlsvKirkState();
|
||||
|
||||
// deceptively named.
|
||||
void Register_sceChnnlsv();
|
||||
void Register_semaphore();
|
||||
|
||||
+6
-3
@@ -45,6 +45,7 @@
|
||||
#include "Core/HLE/FunctionWrappers.h"
|
||||
#include "Core/HLE/sceKernel.h"
|
||||
#include "Core/HLE/sceUmd.h"
|
||||
#include "Core/HLE/sceChnnlsv.h"
|
||||
#include "Core/HW/Display.h"
|
||||
#include "Core/MIPS/MIPS.h"
|
||||
#include "Core/HW/MemoryStick.h"
|
||||
@@ -63,7 +64,6 @@ extern "C" {
|
||||
|
||||
#include "Core/HLE/sceIo.h"
|
||||
#include "Core/HLE/sceRtc.h"
|
||||
#include "Core/HLE/sceKernel.h"
|
||||
#include "Core/HLE/sceKernelMemory.h"
|
||||
#include "Core/HLE/sceKernelThread.h"
|
||||
#include "Core/HLE/sceKernelInterrupt.h"
|
||||
@@ -1009,13 +1009,15 @@ static u32 npdrmRead(FileNode *f, u8 *data, int size) {
|
||||
size = (int)pgd->data_size;
|
||||
remain_size = size;
|
||||
|
||||
KirkState *kirk = __ChnnlsvKirkState();
|
||||
|
||||
while(remain_size){
|
||||
|
||||
if(pgd->current_block!=block){
|
||||
blockPos = block*pgd->block_size;
|
||||
pspFileSystem.SeekFile(f->handle, (s32)pgd->data_offset+blockPos, FILEMOVE_BEGIN);
|
||||
pspFileSystem.ReadFile(f->handle, pgd->block_buf, pgd->block_size);
|
||||
pgd_decrypt_block(pgd, block);
|
||||
pgd_decrypt_block(kirk, pgd, block);
|
||||
pgd->current_block = block;
|
||||
}
|
||||
|
||||
@@ -2580,7 +2582,8 @@ int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 out
|
||||
DEBUG_LOG(Log::sceIo, "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);
|
||||
KirkState *kirk = __ChnnlsvKirkState();
|
||||
f->pgdInfo = pgd_open(kirk, pgd_header, 2, key_ptr);
|
||||
if (!f->pgdInfo) {
|
||||
f->npdrm = false;
|
||||
pspFileSystem.SeekFile(f->handle, (s32)0, FILEMOVE_BEGIN);
|
||||
|
||||
@@ -419,33 +419,3 @@ int sceKernelPollSema(SceUID id, int wantedCount) {
|
||||
return hleLogDebug(Log::sceKernel, SCE_KERNEL_ERROR_SEMA_ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
// The below functions don't really belong to sceKernelSemaphore. They are the core crypto functionality,
|
||||
// exposed through the confusingly named "sceUtilsBufferCopyWithRange" name, which Sony placed in the
|
||||
// not-at-all-suspicious "semaphore" library, which has nothing to do with semaphores.
|
||||
|
||||
static u32 sceUtilsBufferCopyWithRange(u32 outAddr, int outSize, u32 inAddr, int inSize, int cmd) {
|
||||
u8 *outAddress = Memory::IsValidRange(outAddr, outSize) ? Memory::GetPointerWriteUnchecked(outAddr) : nullptr;
|
||||
u8 *inAddress = Memory::IsValidRange(inAddr, inSize) ? Memory::GetPointerWriteUnchecked(inAddr) : nullptr;
|
||||
int temp = kirk_sceUtilsBufferCopyWithRange(outAddress, outSize, inAddress, inSize, cmd);
|
||||
if (temp != 0) {
|
||||
ERROR_LOG(Log::sceKernel, "hleUtilsBufferCopyWithRange: Failed with %d", temp);
|
||||
}
|
||||
return hleNoLog(0);
|
||||
}
|
||||
|
||||
// Note sure what difference there is between this and sceUtilsBufferCopyWithRange.
|
||||
static int sceUtilsBufferCopyByPollingWithRange(u32 outAddr, int outSize, u32 inAddr, int inSize, int cmd) {
|
||||
u8 *outAddress = Memory::IsValidRange(outAddr, outSize) ? Memory::GetPointerWriteUnchecked(outAddr) : nullptr;
|
||||
u8 *inAddress = Memory::IsValidRange(inAddr, inSize) ? Memory::GetPointerWriteUnchecked(inAddr) : nullptr;
|
||||
return hleNoLog(kirk_sceUtilsBufferCopyWithRange(outAddress, outSize, inAddress, inSize, cmd));
|
||||
}
|
||||
|
||||
const HLEFunction semaphore[] = {
|
||||
{0x4C537C72, &WrapU_UIUII<sceUtilsBufferCopyWithRange>, "sceUtilsBufferCopyWithRange", 'x', "xixii" },
|
||||
{0x77E97079, &WrapI_UIUII<sceUtilsBufferCopyByPollingWithRange>, "sceUtilsBufferCopyByPollingWithRange", 'i', "xixii" },
|
||||
};
|
||||
|
||||
void Register_semaphore() {
|
||||
RegisterHLEModule("semaphore", ARRAY_SIZE(semaphore), semaphore);
|
||||
}
|
||||
|
||||
@@ -32,9 +32,7 @@ void __KernelSemaInit();
|
||||
void __KernelSemaDoState(PointerWrap &p);
|
||||
KernelObject *__KernelSemaphoreObject();
|
||||
|
||||
void Register_semaphore();
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ext/libkirk/kirk_engine.h"
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#ifndef __RIJNDAEL_H
|
||||
#define __RIJNDAEL_H
|
||||
|
||||
#include "kirk_engine.h"
|
||||
#include "kirk_common.h"
|
||||
|
||||
#define AES_KEY_LEN_128 (128)
|
||||
#define AES_KEY_LEN_192 (192)
|
||||
|
||||
+3
-20
@@ -1,5 +1,6 @@
|
||||
#ifndef _GLOBAL_H_
|
||||
#define _GLOBAL_H_ 1
|
||||
#pragma once
|
||||
|
||||
#include "kirk_common.h"
|
||||
|
||||
/* POINTER defines a generic pointer type */
|
||||
typedef unsigned char *POINTER;
|
||||
@@ -16,15 +17,6 @@ typedef unsigned char BYTE;
|
||||
#define TRUE ( !FALSE )
|
||||
#endif /* TRUE */
|
||||
|
||||
#endif /* end _GLOBAL_H_ */
|
||||
|
||||
/* sha.h */
|
||||
|
||||
#ifndef _SHA_H_
|
||||
#define _SHA_H_ 1
|
||||
|
||||
/* #include "global.h" */
|
||||
|
||||
/* The structure for storing SHS info */
|
||||
|
||||
typedef struct
|
||||
@@ -41,13 +33,4 @@ void SHAInit(SHA_CTX *);
|
||||
void SHAUpdate(SHA_CTX *, const BYTE *buffer, int count);
|
||||
void SHAFinal(BYTE *output, SHA_CTX *);
|
||||
|
||||
#endif /* end _SHA_H_ */
|
||||
|
||||
/* endian.h */
|
||||
|
||||
#ifndef _ENDIAN_H_
|
||||
#define _ENDIAN_H_ 1
|
||||
|
||||
void endianTest(int *endianness);
|
||||
|
||||
#endif /* end _ENDIAN_H_ */
|
||||
|
||||
+64
-66
@@ -26,11 +26,9 @@ static const u8 loc_1CD4[16] = {0xE3, 0x50, 0xED, 0x1D, 0x91, 0x0A, 0x1F, 0xD0,
|
||||
static const u8 loc_1CE4[16] = {0x13, 0x5F, 0xA4, 0x7C, 0xAB, 0x39, 0x5B, 0xA4, 0x76, 0xB8, 0xCC, 0xA9, 0x8F, 0x3A, 0x04, 0x45};
|
||||
static const u8 loc_1CF4[16] = {0x67, 0x8D, 0x7F, 0xA3, 0x2A, 0x9C, 0xA0, 0xD1, 0x50, 0x8A, 0xD8, 0x38, 0x5E, 0x4B, 0x01, 0x7E};
|
||||
|
||||
static u8 kirk_buf[0x0814]; // 1DC0 1DD4
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
static int do_kirk4(u8 *buf, int size, int type)
|
||||
static int do_kirk4(KirkState *kirk, u8 *buf, int size, int type)
|
||||
{
|
||||
int retv;
|
||||
u32 *header = (u32*)buf;
|
||||
@@ -41,7 +39,7 @@ static int do_kirk4(u8 *buf, int size, int type)
|
||||
header[3] = type;
|
||||
header[4] = size;
|
||||
|
||||
retv = kirk_sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 4);
|
||||
retv = kirk_sceUtilsBufferCopyWithRange(kirk, buf, size+0x14, buf, size, 4);
|
||||
|
||||
if(retv)
|
||||
return 0x80510311;
|
||||
@@ -49,7 +47,7 @@ static int do_kirk4(u8 *buf, int size, int type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_kirk7(u8 *buf, int size, int type)
|
||||
static int do_kirk7(KirkState *kirk, u8 *buf, int size, int type)
|
||||
{
|
||||
int retv;
|
||||
u32 *header = (u32*)buf;
|
||||
@@ -60,14 +58,14 @@ static int do_kirk7(u8 *buf, int size, int type)
|
||||
header[3] = type;
|
||||
header[4] = size;
|
||||
|
||||
retv = kirk_sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 7);
|
||||
retv = kirk_sceUtilsBufferCopyWithRange(kirk, buf, size+0x14, buf, size, 7);
|
||||
if(retv)
|
||||
return 0x80510311;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kirk5(u8 *buf, int size)
|
||||
static int kirk5(KirkState *kirk, u8 *buf, int size)
|
||||
{
|
||||
int retv;
|
||||
u32 *header = (u32*)buf;
|
||||
@@ -78,14 +76,14 @@ static int kirk5(u8 *buf, int size)
|
||||
header[3] = 0x0100;
|
||||
header[4] = size;
|
||||
|
||||
retv = kirk_sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 5);
|
||||
retv = kirk_sceUtilsBufferCopyWithRange(kirk, buf, size+0x14, buf, size, 5);
|
||||
if(retv)
|
||||
return 0x80510312;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kirk8(u8 *buf, int size)
|
||||
static int kirk8(KirkState *kirk, u8 *buf, int size)
|
||||
{
|
||||
int retv;
|
||||
u32 *header = (u32*)buf;
|
||||
@@ -96,18 +94,18 @@ static int kirk8(u8 *buf, int size)
|
||||
header[3] = 0x0100;
|
||||
header[4] = size;
|
||||
|
||||
retv = kirk_sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 8);
|
||||
retv = kirk_sceUtilsBufferCopyWithRange(kirk, buf, size+0x14, buf, size, 8);
|
||||
if(retv)
|
||||
return 0x80510312;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kirk14(u8 *buf)
|
||||
static int kirk14(KirkState *kirk, u8 *buf)
|
||||
{
|
||||
int retv;
|
||||
|
||||
retv = kirk_sceUtilsBufferCopyWithRange(buf, 0x14, 0, 0, 14);
|
||||
retv = kirk_sceUtilsBufferCopyWithRange(kirk, buf, 0x14, 0, 0, 14);
|
||||
if(retv)
|
||||
return 0x80510315;
|
||||
|
||||
@@ -118,7 +116,7 @@ static int kirk14(u8 *buf)
|
||||
|
||||
// Called by sceDrmBBMacUpdate
|
||||
// encrypt_buf
|
||||
static int sub_158(u8 *buf, int size, u8 *key, int key_type)
|
||||
static int sub_158(KirkState *kirk, u8 *buf, int size, u8 *key, int key_type)
|
||||
{
|
||||
int i, retv;
|
||||
|
||||
@@ -126,7 +124,7 @@ static int sub_158(u8 *buf, int size, u8 *key, int key_type)
|
||||
buf[0x14+i] ^= key[i];
|
||||
}
|
||||
|
||||
retv = do_kirk4(buf, size, key_type);
|
||||
retv = do_kirk4(kirk, buf, size, key_type);
|
||||
if(retv)
|
||||
return retv;
|
||||
|
||||
@@ -151,7 +149,7 @@ int sceDrmBBMacInit(MAC_KEY *mkey, int type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sceDrmBBMacUpdate(MAC_KEY *mkey, u8 *buf, int size)
|
||||
int sceDrmBBMacUpdate(KirkState *kirk, MAC_KEY *mkey, u8 *buf, int size)
|
||||
{
|
||||
int retv = 0, ksize, p, type;
|
||||
u8 *kbuf;
|
||||
@@ -166,7 +164,7 @@ int sceDrmBBMacUpdate(MAC_KEY *mkey, u8 *buf, int size)
|
||||
mkey->pad_size += size;
|
||||
retv = 0;
|
||||
}else{
|
||||
kbuf = kirk_buf+0x14;
|
||||
kbuf = kirk->kirk_buf+0x14;
|
||||
// copy pad data first
|
||||
memcpy(kbuf, mkey->pad, mkey->pad_size);
|
||||
|
||||
@@ -186,7 +184,7 @@ int sceDrmBBMacUpdate(MAC_KEY *mkey, u8 *buf, int size)
|
||||
while(size){
|
||||
ksize = (size+p>=0x0800)? 0x0800 : size+p;
|
||||
memcpy(kbuf+p, buf, ksize-p);
|
||||
retv = sub_158(kirk_buf, ksize, mkey->key, type);
|
||||
retv = sub_158(kirk, kirk->kirk_buf, ksize, mkey->key, type);
|
||||
if(retv)
|
||||
goto _exit;
|
||||
size -= (ksize-p);
|
||||
@@ -200,7 +198,7 @@ _exit:
|
||||
|
||||
}
|
||||
|
||||
int sceDrmBBMacFinal(MAC_KEY *mkey, u8 *buf, u8 *vkey)
|
||||
int sceDrmBBMacFinal(KirkState *kirk, MAC_KEY *mkey, u8 *buf, u8 *vkey)
|
||||
{
|
||||
int i, retv, code;
|
||||
u8 *kbuf, tmp[16], tmp1[16];
|
||||
@@ -210,10 +208,10 @@ int sceDrmBBMacFinal(MAC_KEY *mkey, u8 *buf, u8 *vkey)
|
||||
return 0x80510302;
|
||||
|
||||
code = (mkey->type==2)? 0x3A : 0x38;
|
||||
kbuf = kirk_buf+0x14;
|
||||
kbuf = kirk->kirk_buf+0x14;
|
||||
|
||||
memset(kbuf, 0, 16);
|
||||
retv = do_kirk4(kirk_buf, 16, code);
|
||||
retv = do_kirk4(kirk, kirk->kirk_buf, 16, code);
|
||||
if(retv)
|
||||
goto _exit;
|
||||
memcpy(tmp, kbuf, 16);
|
||||
@@ -262,7 +260,7 @@ int sceDrmBBMacFinal(MAC_KEY *mkey, u8 *buf, u8 *vkey)
|
||||
memcpy(kbuf, mkey->pad, 16);
|
||||
memcpy(tmp1, mkey->key, 16);
|
||||
|
||||
retv = sub_158(kirk_buf, 0x10, tmp1, code);
|
||||
retv = sub_158(kirk, kirk->kirk_buf, 0x10, tmp1, code);
|
||||
if(retv)
|
||||
return retv;
|
||||
|
||||
@@ -273,11 +271,11 @@ int sceDrmBBMacFinal(MAC_KEY *mkey, u8 *buf, u8 *vkey)
|
||||
if(mkey->type==2){
|
||||
memcpy(kbuf, tmp1, 16);
|
||||
|
||||
retv = kirk5(kirk_buf, 0x10);
|
||||
retv = kirk5(kirk, kirk->kirk_buf, 0x10);
|
||||
if(retv)
|
||||
goto _exit;
|
||||
|
||||
retv = do_kirk4(kirk_buf, 0x10, code);
|
||||
retv = do_kirk4(kirk, kirk->kirk_buf, 0x10, code);
|
||||
if(retv)
|
||||
goto _exit;
|
||||
|
||||
@@ -290,7 +288,7 @@ int sceDrmBBMacFinal(MAC_KEY *mkey, u8 *buf, u8 *vkey)
|
||||
}
|
||||
memcpy(kbuf, tmp1, 16);
|
||||
|
||||
retv = do_kirk4(kirk_buf, 0x10, code);
|
||||
retv = do_kirk4(kirk, kirk->kirk_buf, 0x10, code);
|
||||
if(retv)
|
||||
goto _exit;
|
||||
|
||||
@@ -310,29 +308,29 @@ _exit:
|
||||
return retv;
|
||||
}
|
||||
|
||||
int sceDrmBBMacFinal2(MAC_KEY *mkey, u8 *out, u8 *vkey)
|
||||
int sceDrmBBMacFinal2(KirkState *kirk, MAC_KEY *mkey, u8 *out, u8 *vkey)
|
||||
{
|
||||
int i, retv, type;
|
||||
u8 *kbuf, tmp[16];
|
||||
|
||||
type = mkey->type;
|
||||
retv = sceDrmBBMacFinal(mkey, tmp, vkey);
|
||||
retv = sceDrmBBMacFinal(kirk, mkey, tmp, vkey);
|
||||
if(retv)
|
||||
return retv;
|
||||
|
||||
kbuf = kirk_buf+0x14;
|
||||
kbuf = kirk->kirk_buf+0x14;
|
||||
|
||||
// decrypt bbmac
|
||||
if(type==3){
|
||||
memcpy(kbuf, out, 0x10);
|
||||
do_kirk7(kirk_buf, 0x10, 0x63);
|
||||
do_kirk7(kirk, kirk->kirk_buf, 0x10, 0x63);
|
||||
}else{
|
||||
memcpy(kirk_buf, out, 0x10);
|
||||
memcpy(kirk->kirk_buf, out, 0x10);
|
||||
}
|
||||
|
||||
retv = 0;
|
||||
for(i=0; i<0x10; i++){
|
||||
if(kirk_buf[i]!=tmp[i]){
|
||||
if(kirk->kirk_buf[i]!=tmp[i]){
|
||||
retv = 0x80510300;
|
||||
break;
|
||||
}
|
||||
@@ -342,34 +340,34 @@ int sceDrmBBMacFinal2(MAC_KEY *mkey, u8 *out, u8 *vkey)
|
||||
}
|
||||
|
||||
// get key from bbmac
|
||||
int bbmac_getkey(MAC_KEY *mkey, u8 *bbmac, u8 *vkey)
|
||||
int bbmac_getkey(KirkState *kirk, 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);
|
||||
retv = sceDrmBBMacFinal(kirk, mkey, tmp, NULL);
|
||||
if(retv)
|
||||
return retv;
|
||||
|
||||
kbuf = kirk_buf+0x14;
|
||||
kbuf = kirk->kirk_buf+0x14;
|
||||
|
||||
// decrypt bbmac
|
||||
if(type==3){
|
||||
memcpy(kbuf, bbmac, 0x10);
|
||||
do_kirk7(kirk_buf, 0x10, 0x63);
|
||||
do_kirk7(kirk, kirk->kirk_buf, 0x10, 0x63);
|
||||
}else{
|
||||
memcpy(kirk_buf, bbmac, 0x10);
|
||||
memcpy(kirk->kirk_buf, bbmac, 0x10);
|
||||
}
|
||||
|
||||
memcpy(tmp1, kirk_buf, 16);
|
||||
memcpy(tmp1, kirk->kirk_buf, 16);
|
||||
memcpy(kbuf, tmp1, 16);
|
||||
|
||||
code = (type==2)? 0x3A : 0x38;
|
||||
do_kirk7(kirk_buf, 0x10, code);
|
||||
do_kirk7(kirk, kirk->kirk_buf, 0x10, code);
|
||||
|
||||
for(i=0; i<0x10; i++){
|
||||
vkey[i] = tmp[i] ^ kirk_buf[i];
|
||||
vkey[i] = tmp[i] ^ kirk->kirk_buf[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -377,7 +375,7 @@ int bbmac_getkey(MAC_KEY *mkey, u8 *bbmac, u8 *vkey)
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
static int sub_1F8(u8 *buf, int size, u8 *key, int key_type)
|
||||
static int sub_1F8(KirkState *kirk, u8 *buf, int size, u8 *key, int key_type)
|
||||
{
|
||||
int i, retv;
|
||||
u8 tmp[16];
|
||||
@@ -385,7 +383,7 @@ static int sub_1F8(u8 *buf, int size, u8 *key, int key_type)
|
||||
// copy last 16 bytes to tmp
|
||||
memcpy(tmp, buf+size+0x14-16, 16);
|
||||
|
||||
retv = do_kirk7(buf, size, key_type);
|
||||
retv = do_kirk7(kirk, buf, size, key_type);
|
||||
if(retv)
|
||||
return retv;
|
||||
|
||||
@@ -400,7 +398,7 @@ static int sub_1F8(u8 *buf, int size, u8 *key, int key_type)
|
||||
}
|
||||
|
||||
|
||||
static int sub_428(u8 *kbuf, u8 *dbuf, int size, CIPHER_KEY *ckey)
|
||||
static int sub_428(KirkState *kirk, u8 *kbuf, u8 *dbuf, int size, CIPHER_KEY *ckey)
|
||||
{
|
||||
int i, retv;
|
||||
u8 tmp1[16], tmp2[16];
|
||||
@@ -412,9 +410,9 @@ static int sub_428(u8 *kbuf, u8 *dbuf, int size, CIPHER_KEY *ckey)
|
||||
}
|
||||
|
||||
if(ckey->type==2)
|
||||
retv = kirk8(kbuf, 16);
|
||||
retv = kirk8(kirk, kbuf, 16);
|
||||
else
|
||||
retv = do_kirk7(kbuf, 16, 0x39);
|
||||
retv = do_kirk7(kirk, kbuf, 16, 0x39);
|
||||
if(retv)
|
||||
return retv;
|
||||
|
||||
@@ -437,7 +435,7 @@ static int sub_428(u8 *kbuf, u8 *dbuf, int size, CIPHER_KEY *ckey)
|
||||
ckey->seed += 1;
|
||||
}
|
||||
|
||||
retv = sub_1F8(kbuf, size, tmp1, 0x63);
|
||||
retv = sub_1F8(kirk, kbuf, size, tmp1, 0x63);
|
||||
if(retv)
|
||||
return retv;
|
||||
|
||||
@@ -452,12 +450,12 @@ static int sub_428(u8 *kbuf, u8 *dbuf, int size, CIPHER_KEY *ckey)
|
||||
// 2 use fuse id
|
||||
// mode: 1 for encrypt
|
||||
// 2 for decrypt
|
||||
int sceDrmBBCipherInit(CIPHER_KEY *ckey, int type, int mode, u8 *header_key, u8 *version_key, u32 seed)
|
||||
int sceDrmBBCipherInit(KirkState *kirk, CIPHER_KEY *ckey, int type, int mode, u8 *header_key, u8 *version_key, u32 seed)
|
||||
{
|
||||
int i, retv;
|
||||
u8 *kbuf;
|
||||
|
||||
kbuf = kirk_buf+0x14;
|
||||
kbuf = kirk->kirk_buf+0x14;
|
||||
ckey->type = type;
|
||||
if(mode==2){
|
||||
ckey->seed = seed+1;
|
||||
@@ -472,18 +470,18 @@ int sceDrmBBCipherInit(CIPHER_KEY *ckey, int type, int mode, u8 *header_key, u8
|
||||
retv = 0;
|
||||
}else if(mode==1){
|
||||
ckey->seed = 1;
|
||||
retv = kirk14(kirk_buf);
|
||||
retv = kirk14(kirk, kirk->kirk_buf);
|
||||
if(retv)
|
||||
return retv;
|
||||
|
||||
memcpy(kbuf, kirk_buf, 0x10);
|
||||
memcpy(kbuf, kirk->kirk_buf, 0x10);
|
||||
memset(kbuf+0x0c, 0, 4);
|
||||
|
||||
if(ckey->type==2){
|
||||
for(i=0; i<16; i++){
|
||||
kbuf[i] ^= loc_1CE4[i];
|
||||
}
|
||||
retv = kirk5(kirk_buf, 0x10);
|
||||
retv = kirk5(kirk, kirk->kirk_buf, 0x10);
|
||||
for(i=0; i<16; i++){
|
||||
kbuf[i] ^= loc_1CF4[i];
|
||||
}
|
||||
@@ -491,7 +489,7 @@ int sceDrmBBCipherInit(CIPHER_KEY *ckey, int type, int mode, u8 *header_key, u8
|
||||
for(i=0; i<16; i++){
|
||||
kbuf[i] ^= loc_1CE4[i];
|
||||
}
|
||||
retv = do_kirk4(kirk_buf, 0x10, 0x39);
|
||||
retv = do_kirk4(kirk, kirk->kirk_buf, 0x10, 0x39);
|
||||
for(i=0; i<16; i++){
|
||||
kbuf[i] ^= loc_1CF4[i];
|
||||
}
|
||||
@@ -514,7 +512,7 @@ int sceDrmBBCipherInit(CIPHER_KEY *ckey, int type, int mode, u8 *header_key, u8
|
||||
return retv;
|
||||
}
|
||||
|
||||
int sceDrmBBCipherUpdate(CIPHER_KEY *ckey, u8 *data, int size)
|
||||
int sceDrmBBCipherUpdate(KirkState *kirk, CIPHER_KEY *ckey, u8 *data, int size)
|
||||
{
|
||||
int p, retv, dsize;
|
||||
|
||||
@@ -523,7 +521,7 @@ int sceDrmBBCipherUpdate(CIPHER_KEY *ckey, u8 *data, int size)
|
||||
|
||||
while(size>0){
|
||||
dsize = (size>=0x0800)? 0x0800 : size;
|
||||
retv = sub_428(kirk_buf, data+p, dsize, ckey);
|
||||
retv = sub_428(kirk, kirk->kirk_buf, data+p, dsize, ckey);
|
||||
if(retv)
|
||||
break;
|
||||
size -= dsize;
|
||||
@@ -555,7 +553,7 @@ static const u8 key_363C[16] = {
|
||||
0x38,0x20,0xD0,0x11,0x07,0xA3,0xFF,0x3E,0x0A,0x4C,0x20,0x85,0x39,0x10,0xB5,0x54,
|
||||
};
|
||||
|
||||
int sceNpDrmGetFixedKey(u8 *key, char *npstr, int type)
|
||||
int sceNpDrmGetFixedKey(KirkState *kirk, u8 *key, char *npstr, int type)
|
||||
{
|
||||
AES_ctx akey;
|
||||
MAC_KEY mkey;
|
||||
@@ -573,11 +571,11 @@ int sceNpDrmGetFixedKey(u8 *key, char *npstr, int type)
|
||||
if(retv)
|
||||
return retv;
|
||||
|
||||
retv = sceDrmBBMacUpdate(&mkey, (u8*)strbuf, 0x30);
|
||||
retv = sceDrmBBMacUpdate(kirk, &mkey, (u8*)strbuf, 0x30);
|
||||
if(retv)
|
||||
return retv;
|
||||
|
||||
retv = sceDrmBBMacFinal(&mkey, key, (u8*)key_363C);
|
||||
retv = sceDrmBBMacFinal(kirk, &mkey, key, (u8*)key_363C);
|
||||
if(retv)
|
||||
return 0x80550902;
|
||||
|
||||
@@ -600,7 +598,7 @@ int sceNpDrmGetFixedKey(u8 *key, char *npstr, int type)
|
||||
static const u8 dnas_key1A90[] = {0xED,0xE2,0x5D,0x2D,0xBB,0xF8,0x12,0xE5,0x3C,0x5C,0x59,0x32,0xFA,0xE3,0xE2,0x43};
|
||||
static const u8 dnas_key1AA0[] = {0x27,0x74,0xFB,0xEB,0xA4,0xA0, 1,0xD7, 2,0x56,0x9E,0x33,0x8C,0x19,0x57,0x83};
|
||||
|
||||
PGD_DESC *pgd_open(u8 *pgd_buf, int pgd_flag, u8 *pgd_vkey)
|
||||
PGD_DESC *pgd_open(KirkState *kirk, u8 *pgd_buf, int pgd_flag, u8 *pgd_vkey)
|
||||
{
|
||||
PGD_DESC *pgd;
|
||||
MAC_KEY mkey;
|
||||
@@ -644,8 +642,8 @@ PGD_DESC *pgd_open(u8 *pgd_buf, int pgd_flag, u8 *pgd_vkey)
|
||||
|
||||
// MAC_0x80 check
|
||||
sceDrmBBMacInit(&mkey, pgd->mac_type);
|
||||
sceDrmBBMacUpdate(&mkey, pgd_buf+0x00, 0x80);
|
||||
retv = sceDrmBBMacFinal2(&mkey, pgd_buf+0x80, fkey);
|
||||
sceDrmBBMacUpdate(kirk, &mkey, pgd_buf+0x00, 0x80);
|
||||
retv = sceDrmBBMacFinal2(kirk, &mkey, pgd_buf+0x80, fkey);
|
||||
if(retv){
|
||||
//ERROR_LOG(Log::HLE, "pgd_open: MAC_80 check failed!: %08x(%d)\n", retv, retv);
|
||||
free(pgd);
|
||||
@@ -654,10 +652,10 @@ PGD_DESC *pgd_open(u8 *pgd_buf, int pgd_flag, u8 *pgd_vkey)
|
||||
|
||||
// MAC_0x70
|
||||
sceDrmBBMacInit(&mkey, pgd->mac_type);
|
||||
sceDrmBBMacUpdate(&mkey, pgd_buf+0x00, 0x70);
|
||||
sceDrmBBMacUpdate(kirk, &mkey, pgd_buf+0x00, 0x70);
|
||||
if(pgd_vkey){
|
||||
// use given vkey
|
||||
retv = sceDrmBBMacFinal2(&mkey, pgd_buf+0x70, pgd_vkey);
|
||||
retv = sceDrmBBMacFinal2(kirk, &mkey, pgd_buf+0x70, pgd_vkey);
|
||||
if(retv){
|
||||
//ERROR_LOG(Log::HLE, "pgd_open: MAC_70 check failed!: %08x(%d)\n", retv, retv);
|
||||
free(pgd);
|
||||
@@ -667,12 +665,12 @@ PGD_DESC *pgd_open(u8 *pgd_buf, int pgd_flag, u8 *pgd_vkey)
|
||||
}
|
||||
}else{
|
||||
// get vkey from MAC_70
|
||||
bbmac_getkey(&mkey, pgd_buf+0x70, pgd->vkey);
|
||||
bbmac_getkey(kirk, &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);
|
||||
sceDrmBBCipherInit(kirk, &ckey, pgd->cipher_type, 2, pgd_buf+0x10, pgd->vkey, 0);
|
||||
sceDrmBBCipherUpdate(kirk, &ckey, pgd_buf+0x30, 0x30);
|
||||
sceDrmBBCipherFinal(&ckey);
|
||||
|
||||
pgd->data_size = *(u32*)(pgd_buf+0x44);
|
||||
@@ -692,7 +690,7 @@ PGD_DESC *pgd_open(u8 *pgd_buf, int pgd_flag, u8 *pgd_vkey)
|
||||
return pgd;
|
||||
}
|
||||
|
||||
int pgd_decrypt_block(PGD_DESC *pgd, int block)
|
||||
int pgd_decrypt_block(KirkState *kirk, PGD_DESC *pgd, int block)
|
||||
{
|
||||
CIPHER_KEY ckey;
|
||||
u32 block_offset;
|
||||
@@ -700,8 +698,8 @@ int pgd_decrypt_block(PGD_DESC *pgd, int block)
|
||||
block_offset = block*pgd->block_size;
|
||||
|
||||
// decrypt block data
|
||||
sceDrmBBCipherInit(&ckey, pgd->cipher_type, 2, pgd->dkey, pgd->vkey, block_offset>>4);
|
||||
sceDrmBBCipherUpdate(&ckey, pgd->block_buf, pgd->block_size);
|
||||
sceDrmBBCipherInit(kirk, &ckey, pgd->cipher_type, 2, pgd->dkey, pgd->vkey, block_offset>>4);
|
||||
sceDrmBBCipherUpdate(kirk, &ckey, pgd->block_buf, pgd->block_size);
|
||||
sceDrmBBCipherFinal(&ckey);
|
||||
|
||||
return pgd->block_size;
|
||||
|
||||
+17
-12
@@ -1,5 +1,9 @@
|
||||
#ifndef AMCTRL_H
|
||||
#define AMCTRL_H
|
||||
#pragma once
|
||||
#include "kirk_engine.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
@@ -42,25 +46,26 @@ typedef struct {
|
||||
// 2: use fuse id
|
||||
// 3: use fixed key. MAC need encrypt again
|
||||
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);
|
||||
int sceDrmBBMacUpdate(KirkState *kirk, MAC_KEY *mkey, u8 *buf, int size);
|
||||
int sceDrmBBMacFinal(KirkState *kirk, MAC_KEY *mkey, u8 *buf, u8 *vkey);
|
||||
int sceDrmBBMacFinal2(KirkState *kirk, MAC_KEY *mkey, u8 *out, u8 *vkey);
|
||||
int bbmac_getkey(KirkState *kirk, MAC_KEY *mkey, u8 *bbmac, u8 *vkey);
|
||||
|
||||
// type: 1 use fixed key
|
||||
// 2 use fuse id
|
||||
// mode: 1 for encrypt
|
||||
// 2 for decrypt
|
||||
int sceDrmBBCipherInit(CIPHER_KEY *ckey, int type, int mode, u8 *header_key, u8 *version_key, u32 seed);
|
||||
int sceDrmBBCipherUpdate(CIPHER_KEY *ckey, u8 *data, int size);
|
||||
int sceDrmBBCipherInit(KirkState *kirk, CIPHER_KEY *ckey, int type, int mode, u8 *header_key, u8 *version_key, u32 seed);
|
||||
int sceDrmBBCipherUpdate(KirkState *kirk, CIPHER_KEY *ckey, u8 *data, int size);
|
||||
int sceDrmBBCipherFinal(CIPHER_KEY *ckey);
|
||||
|
||||
// npdrm.prx
|
||||
int sceNpDrmGetFixedKey(u8 *key, char *npstr, int type);
|
||||
int sceNpDrmGetFixedKey(KirkState *kirk, u8 *key, char *npstr, int type);
|
||||
|
||||
PGD_DESC *pgd_open(u8 *pgd_buf, int pgd_flag, u8 *pgd_vkey);
|
||||
int pgd_decrypt_block(PGD_DESC *pgd, int block);
|
||||
PGD_DESC *pgd_open(KirkState *kirk, u8 *pgd_buf, int pgd_flag, u8 *pgd_vkey);
|
||||
int pgd_decrypt_block(KirkState *kirk, PGD_DESC *pgd, int block);
|
||||
int pgd_close(PGD_DESC *pgd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+4
-4
@@ -244,7 +244,7 @@ static void point_mul(struct point *d, u8 *a, struct point *b) // a is bignum
|
||||
// Modified from original to support kirk engine use - July 2011
|
||||
// Added call to Kirk Random number generator rather than /dev/random
|
||||
|
||||
static void generate_ecdsa(u8 *outR, u8 *outS, const u8 *k, const u8 *hash)
|
||||
static void generate_ecdsa(KirkState *kirk, u8 *outR, u8 *outS, const u8 *k, const u8 *hash)
|
||||
{
|
||||
u8 e[21];
|
||||
u8 kk[21];
|
||||
@@ -271,7 +271,7 @@ static void generate_ecdsa(u8 *outR, u8 *outS, const u8 *k, const u8 *hash)
|
||||
// R = (mG).x
|
||||
|
||||
// Added call back to kirk PRNG - July 2011
|
||||
kirk_CMD14(m+1, 20);
|
||||
kirk_CMD14(kirk, m+1, 20);
|
||||
m[0] = 0;
|
||||
|
||||
point_mul(&mG, m, &ec_G);
|
||||
@@ -424,9 +424,9 @@ int ecdsa_verify(u8 *hash, u8 *R, u8 *S)
|
||||
return check_ecdsa(&ec_Q, R, S, hash);
|
||||
}
|
||||
|
||||
void ecdsa_sign(u8 *hash, u8 *R, u8 *S)
|
||||
void ecdsa_sign(KirkState *kirk, u8 *hash, u8 *R, u8 *S)
|
||||
{
|
||||
generate_ecdsa(R, S, ec_k, hash);
|
||||
generate_ecdsa(kirk, R, S, ec_k, hash);
|
||||
}
|
||||
|
||||
int point_is_on_curve(u8 *p)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short int u16;
|
||||
typedef unsigned int u32;
|
||||
|
||||
+80
-90
@@ -192,34 +192,28 @@ static const u8 Py1[20] = {0x04, 0x9D, 0xF1, 0xA0, 0x75, 0xC0, 0xE0, 0x4F, 0xB3,
|
||||
|
||||
/* ------------------------- KEY VAULT END ------------------------- */
|
||||
|
||||
// Some randomly selected data for a "key" to add to each randomization
|
||||
static const u8 random_data[0x10] = { 0xA7, 0x2E, 0x4C, 0xB6, 0xC3, 0x34, 0xDF, 0x85, 0x70, 0x01, 0x49, 0xFC, 0xC0, 0x87, 0xC4, 0x77 };
|
||||
// Another randomly selected data for a "key" to add to each randomization
|
||||
static const u8 random_key[0x10] = { 0x07, 0xAB, 0xEF, 0xF8, 0x96, 0x8C, 0xF3, 0xD6, 0x14, 0xE0, 0xEB, 0xB2, 0x9D, 0x8B, 0x4E, 0x74 };
|
||||
|
||||
/* ------------------------- INTERNAL STUFF ------------------------- */
|
||||
typedef struct blah
|
||||
{
|
||||
typedef struct blah {
|
||||
u8 fuseid[8]; //0
|
||||
u8 mesh[0x40]; //0x8
|
||||
} kirk16_data; //0x48
|
||||
|
||||
typedef struct header_keys
|
||||
{
|
||||
typedef struct header_keys {
|
||||
u8 AES[16];
|
||||
u8 CMAC[16];
|
||||
}header_keys; //small struct for temporary keeping AES & CMAC key from CMD1 header
|
||||
|
||||
|
||||
u32 g_fuse90; // This is to match FuseID HW at BC100090 and BC100094
|
||||
u32 g_fuse94;
|
||||
|
||||
AES_ctx aes_kirk1; //global
|
||||
u8 PRNG_DATA[0x14];
|
||||
|
||||
char is_kirk_initialized; //"init" emulation
|
||||
} header_keys; //small struct for temporary keeping AES & CMAC key from CMD1 header
|
||||
|
||||
/* ------------------------- INTERNAL STUFF END ------------------------- */
|
||||
|
||||
|
||||
/* ------------------------- IMPLEMENTATION ------------------------- */
|
||||
|
||||
int kirk_CMD0(u8* outbuff, const u8* inbuff, int size, int generate_trash)
|
||||
int kirk_CMD0(KirkState *kirk, u8* outbuff, const u8* inbuff, int size, int generate_trash)
|
||||
{
|
||||
KIRK_CMD1_HEADER* header = (KIRK_CMD1_HEADER*)outbuff;
|
||||
header_keys *keys = (header_keys *)outbuff; //0-15 AES key, 16-31 CMAC key
|
||||
@@ -229,14 +223,14 @@ int kirk_CMD0(u8* outbuff, const u8* inbuff, int size, int generate_trash)
|
||||
u8 cmac_header_hash[16];
|
||||
u8 cmac_data_hash[16];
|
||||
|
||||
if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
if(kirk->is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
|
||||
memcpy(outbuff, inbuff, size);
|
||||
|
||||
if(header->mode != KIRK_MODE_CMD1) return KIRK_INVALID_MODE;
|
||||
|
||||
//FILL PREDATA WITH RANDOM DATA
|
||||
if(generate_trash) kirk_CMD14(outbuff+sizeof(KIRK_CMD1_HEADER), header->data_offset);
|
||||
if(generate_trash) kirk_CMD14(kirk, outbuff+sizeof(KIRK_CMD1_HEADER), header->data_offset);
|
||||
|
||||
//Make sure data is 16 aligned
|
||||
chk_size = header->data_size;
|
||||
@@ -255,22 +249,22 @@ int kirk_CMD0(u8* outbuff, const u8* inbuff, int size, int generate_trash)
|
||||
memcpy(header->CMAC_data_hash, cmac_data_hash, 16);
|
||||
|
||||
//ENCRYPT KEYS
|
||||
AES_cbc_encrypt(&aes_kirk1, inbuff, outbuff, 16*2);
|
||||
AES_cbc_encrypt(&kirk->aes_kirk1, inbuff, outbuff, 16*2);
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
}
|
||||
|
||||
// This one writes to inbuff.
|
||||
int kirk_CMD1(u8* outbuff, u8* inbuff, int size)
|
||||
int kirk_CMD1(KirkState *kirk, u8* outbuff, u8* inbuff, int size)
|
||||
{
|
||||
const KIRK_CMD1_HEADER* header = (const KIRK_CMD1_HEADER*)inbuff;
|
||||
header_keys keys; //0-15 AES key, 16-31 CMAC key
|
||||
AES_ctx k1;
|
||||
|
||||
if(size < 0x90) return KIRK_INVALID_SIZE;
|
||||
if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
if(kirk->is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
if(header->mode != KIRK_MODE_CMD1) return KIRK_INVALID_MODE;
|
||||
|
||||
AES_cbc_decrypt(&aes_kirk1, inbuff, (u8*)&keys, 16*2); //decrypt AES & CMAC key to temp buffer
|
||||
AES_cbc_decrypt(&kirk->aes_kirk1, inbuff, (u8*)&keys, 16*2); //decrypt AES & CMAC key to temp buffer
|
||||
|
||||
if(header->ecdsa_hash == 1)
|
||||
{
|
||||
@@ -300,7 +294,7 @@ int kirk_CMD1(u8* outbuff, u8* inbuff, int size)
|
||||
}
|
||||
|
||||
} else {
|
||||
int ret = kirk_CMD10(inbuff, size);
|
||||
int ret = kirk_CMD10(kirk, inbuff, size);
|
||||
if(ret != KIRK_OPERATION_SUCCESS) return ret;
|
||||
}
|
||||
|
||||
@@ -310,13 +304,13 @@ int kirk_CMD1(u8* outbuff, u8* inbuff, int size)
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
}
|
||||
|
||||
int kirk_CMD4(u8* outbuff, const u8* inbuff, int size)
|
||||
int kirk_CMD4(KirkState *kirk, u8* outbuff, const u8* inbuff, int size)
|
||||
{
|
||||
const KIRK_AES128CBC_HEADER *header = (const KIRK_AES128CBC_HEADER*)inbuff;
|
||||
const u8* key;
|
||||
AES_ctx aesKey;
|
||||
|
||||
if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
if(kirk->is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
if(header->mode != KIRK_MODE_ENCRYPT_CBC) return KIRK_INVALID_MODE;
|
||||
if(header->data_size == 0) return KIRK_DATA_SIZE_ZERO;
|
||||
|
||||
@@ -338,13 +332,13 @@ void kirk4(u8* outbuff, const u8* inbuff, size_t size, int keyId)
|
||||
AES_cbc_encrypt(&aesKey, inbuff, outbuff, (int)size);
|
||||
}
|
||||
|
||||
int kirk_CMD7(u8* outbuff, const u8* inbuff, int size)
|
||||
int kirk_CMD7(KirkState *kirk, u8* outbuff, const u8* inbuff, int size)
|
||||
{
|
||||
KIRK_AES128CBC_HEADER *header = (KIRK_AES128CBC_HEADER*)inbuff;
|
||||
const u8* key;
|
||||
AES_ctx aesKey;
|
||||
|
||||
if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
if(kirk->is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
if(header->mode != KIRK_MODE_DECRYPT_CBC) return KIRK_INVALID_MODE;
|
||||
if(header->data_size == 0) return KIRK_DATA_SIZE_ZERO;
|
||||
|
||||
@@ -367,7 +361,7 @@ void kirk7(u8* outbuff, const u8* inbuff, size_t size, int keyId)
|
||||
}
|
||||
|
||||
// This one works in-place.
|
||||
int kirk_CMD10(u8* inbuff, int insize)
|
||||
int kirk_CMD10(KirkState *kirk, u8* inbuff, int insize)
|
||||
{
|
||||
KIRK_CMD1_HEADER* header = (KIRK_CMD1_HEADER*)inbuff;
|
||||
header_keys keys; //0-15 AES key, 16-31 CMAC key
|
||||
@@ -376,13 +370,13 @@ int kirk_CMD10(u8* inbuff, int insize)
|
||||
AES_ctx cmac_key;
|
||||
int chk_size;
|
||||
|
||||
if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
if(kirk->is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
if(!(header->mode == KIRK_MODE_CMD1 || header->mode == KIRK_MODE_CMD2 || header->mode == KIRK_MODE_CMD3)) return KIRK_INVALID_MODE;
|
||||
if(header->data_size == 0) return KIRK_DATA_SIZE_ZERO;
|
||||
|
||||
if(header->mode == KIRK_MODE_CMD1)
|
||||
{
|
||||
AES_cbc_decrypt(&aes_kirk1, inbuff, (u8*)&keys, 32); //decrypt AES & CMAC key to temp buffer
|
||||
AES_cbc_decrypt(&kirk->aes_kirk1, inbuff, (u8*)&keys, 32); //decrypt AES & CMAC key to temp buffer
|
||||
AES_set_key(&cmac_key, keys.CMAC, 128);
|
||||
AES_CMAC(&cmac_key, inbuff+0x60, 0x30, cmac_header_hash);
|
||||
|
||||
@@ -399,11 +393,11 @@ int kirk_CMD10(u8* inbuff, int insize)
|
||||
return KIRK_SIG_CHECK_INVALID; //Checks for cmd 2 & 3 not included right now
|
||||
}
|
||||
|
||||
int kirk_CMD11(u8* outbuff, const u8* inbuff, int size)
|
||||
int kirk_CMD11(KirkState *kirk, u8* outbuff, const u8* inbuff, int size)
|
||||
{
|
||||
KIRK_SHA1_HEADER *header = (KIRK_SHA1_HEADER *)inbuff;
|
||||
SHA_CTX sha;
|
||||
if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
if(kirk->is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
if(header->data_size == 0 || size == 0) return KIRK_DATA_SIZE_ZERO;
|
||||
|
||||
SHAInit(&sha);
|
||||
@@ -415,14 +409,14 @@ int kirk_CMD11(u8* outbuff, const u8* inbuff, int size)
|
||||
// Generate an ECDSA Key pair
|
||||
// offset 0 = private key (0x14 len)
|
||||
// offset 0x14 = public key point (0x28 len)
|
||||
int kirk_CMD12(u8 *outbuff, int outsize) {
|
||||
int kirk_CMD12(KirkState *kirk, u8 *outbuff, int outsize) {
|
||||
u8 k[0x15];
|
||||
KIRK_CMD12_BUFFER * keypair = (KIRK_CMD12_BUFFER *) outbuff;
|
||||
|
||||
if(outsize != 0x3C) return KIRK_INVALID_SIZE;
|
||||
ecdsa_set_curve(ec_p,ec_a,ec_b2,ec_N2,Gx2,Gy2);
|
||||
k[0] = 0;
|
||||
kirk_CMD14(k+1,0x14);
|
||||
kirk_CMD14(kirk, k+1,0x14);
|
||||
ec_priv_to_pub(k, (u8*)keypair->public_key.x);
|
||||
memcpy(keypair->private_key,k+1,0x14);
|
||||
|
||||
@@ -432,7 +426,7 @@ int kirk_CMD12(u8 *outbuff, int outsize) {
|
||||
// Point multiplication
|
||||
// offset 0 = mulitplication value (0x14 len)
|
||||
// offset 0x14 = point to multiply (0x28 len)
|
||||
int kirk_CMD13(u8 * outbuff, int outsize,u8 * inbuff, int insize) {
|
||||
int kirk_CMD13(KirkState *kirk, u8 * outbuff, int outsize,u8 * inbuff, int insize) {
|
||||
u8 k[0x15];
|
||||
KIRK_CMD13_BUFFER * pointmult = (KIRK_CMD13_BUFFER *) inbuff;
|
||||
k[0]=0;
|
||||
@@ -445,20 +439,18 @@ int kirk_CMD13(u8 * outbuff, int outsize,u8 * inbuff, int insize) {
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
}
|
||||
|
||||
int kirk_CMD14(u8 *outbuff, int outsize) {
|
||||
int kirk_CMD14(KirkState *kirk, u8 *outbuff, int outsize) {
|
||||
u8 temp[0x104];
|
||||
// This was added to mollify valgrind.
|
||||
memset(temp, 0xAA, sizeof(temp));
|
||||
|
||||
KIRK_SHA1_HEADER *header = (KIRK_SHA1_HEADER *) temp;
|
||||
|
||||
// Some randomly selected data for a "key" to add to each randomization
|
||||
static const u8 random_data[0x10] = { 0xA7, 0x2E, 0x4C, 0xB6, 0xC3, 0x34, 0xDF, 0x85, 0x70, 0x01, 0x49, 0xFC, 0xC0, 0x87, 0xC4, 0x77 };
|
||||
u32 curtime;
|
||||
//if(outsize != 0x14) return KIRK_INVALID_SIZE; // Need real error code
|
||||
if(outsize <=0) return KIRK_OPERATION_SUCCESS;
|
||||
|
||||
memcpy(temp+4, PRNG_DATA,0x14);
|
||||
memcpy(temp+4, kirk->PRNG_DATA,0x14);
|
||||
// This uses the standard C time function for portability.
|
||||
curtime = (u32)time(0);
|
||||
temp[0x18] = curtime &0xFF;
|
||||
@@ -471,7 +463,7 @@ int kirk_CMD14(u8 *outbuff, int outsize) {
|
||||
// This leaves the remainder of the 0x100 bytes in temp to whatever remains on the stack
|
||||
// in an uninitialized state. This should add unpredicableness to the results as well
|
||||
header->data_size=0x100;
|
||||
kirk_CMD11(PRNG_DATA, temp, 0x104);
|
||||
kirk_CMD11(kirk, kirk->PRNG_DATA, temp, 0x104);
|
||||
while(outsize)
|
||||
{
|
||||
int blockrem= outsize %0x14;
|
||||
@@ -479,14 +471,14 @@ int kirk_CMD14(u8 *outbuff, int outsize) {
|
||||
|
||||
if(block)
|
||||
{
|
||||
memcpy(outbuff, PRNG_DATA, 0x14);
|
||||
memcpy(outbuff, kirk->PRNG_DATA, 0x14);
|
||||
outbuff+=0x14;
|
||||
outsize -= 0x14;
|
||||
kirk_CMD14(outbuff, outsize);
|
||||
kirk_CMD14(kirk, outbuff, outsize);
|
||||
} else {
|
||||
if(blockrem)
|
||||
{
|
||||
memcpy(outbuff, PRNG_DATA, blockrem);
|
||||
memcpy(outbuff, kirk->PRNG_DATA, blockrem);
|
||||
outsize -= blockrem;
|
||||
}
|
||||
}
|
||||
@@ -495,21 +487,21 @@ int kirk_CMD14(u8 *outbuff, int outsize) {
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
}
|
||||
|
||||
void decrypt_kirk16_private(u8 *dA_out, u8 *dA_enc)
|
||||
void decrypt_kirk16_private(KirkState *kirk, u8 *dA_out, u8 *dA_enc)
|
||||
{
|
||||
int i, k;
|
||||
kirk16_data keydata;
|
||||
u8 subkey_1[0x10], subkey_2[0x10];
|
||||
rijndael_ctx aes_ctx;
|
||||
|
||||
keydata.fuseid[7] = g_fuse90 &0xFF;
|
||||
keydata.fuseid[6] = (g_fuse90>>8) &0xFF;
|
||||
keydata.fuseid[5] = (g_fuse90>>16) &0xFF;
|
||||
keydata.fuseid[4] = (g_fuse90>>24) &0xFF;
|
||||
keydata.fuseid[3] = g_fuse94 &0xFF;
|
||||
keydata.fuseid[2] = (g_fuse94>>8) &0xFF;
|
||||
keydata.fuseid[1] = (g_fuse94>>16) &0xFF;
|
||||
keydata.fuseid[0] = (g_fuse94>>24) &0xFF;
|
||||
keydata.fuseid[7] = kirk->g_fuse90 &0xFF;
|
||||
keydata.fuseid[6] = (kirk->g_fuse90>>8) &0xFF;
|
||||
keydata.fuseid[5] = (kirk->g_fuse90>>16) &0xFF;
|
||||
keydata.fuseid[4] = (kirk->g_fuse90>>24) &0xFF;
|
||||
keydata.fuseid[3] = kirk->g_fuse94 &0xFF;
|
||||
keydata.fuseid[2] = (kirk->g_fuse94>>8) &0xFF;
|
||||
keydata.fuseid[1] = (kirk->g_fuse94>>16) &0xFF;
|
||||
keydata.fuseid[0] = (kirk->g_fuse94>>24) &0xFF;
|
||||
|
||||
/* set encryption key */
|
||||
rijndael_set_key(&aes_ctx, kirk16_key, 128);
|
||||
@@ -563,7 +555,7 @@ void decrypt_kirk16_private(u8 *dA_out, u8 *dA_enc)
|
||||
AES_cbc_decrypt((AES_ctx *)&aes_ctx, dA_enc, dA_out, 0x20);
|
||||
}
|
||||
|
||||
void encrypt_kirk16_private(u8 *dA_out, u8 *dA_dec)
|
||||
void encrypt_kirk16_private(KirkState *kirk, u8 *dA_out, u8 *dA_dec)
|
||||
{
|
||||
int i, k;
|
||||
kirk16_data keydata;
|
||||
@@ -571,14 +563,14 @@ void encrypt_kirk16_private(u8 *dA_out, u8 *dA_dec)
|
||||
rijndael_ctx aes_ctx;
|
||||
|
||||
|
||||
keydata.fuseid[7] = g_fuse90 &0xFF;
|
||||
keydata.fuseid[6] = (g_fuse90>>8) &0xFF;
|
||||
keydata.fuseid[5] = (g_fuse90>>16) &0xFF;
|
||||
keydata.fuseid[4] = (g_fuse90>>24) &0xFF;
|
||||
keydata.fuseid[3] = g_fuse94 &0xFF;
|
||||
keydata.fuseid[2] = (g_fuse94>>8) &0xFF;
|
||||
keydata.fuseid[1] = (g_fuse94>>16) &0xFF;
|
||||
keydata.fuseid[0] = (g_fuse94>>24) &0xFF;
|
||||
keydata.fuseid[7] = kirk->g_fuse90 &0xFF;
|
||||
keydata.fuseid[6] = (kirk->g_fuse90>>8) &0xFF;
|
||||
keydata.fuseid[5] = (kirk->g_fuse90>>16) &0xFF;
|
||||
keydata.fuseid[4] = (kirk->g_fuse90>>24) &0xFF;
|
||||
keydata.fuseid[3] = kirk->g_fuse94 &0xFF;
|
||||
keydata.fuseid[2] = (kirk->g_fuse94>>8) &0xFF;
|
||||
keydata.fuseid[1] = (kirk->g_fuse94>>16) &0xFF;
|
||||
keydata.fuseid[0] = (kirk->g_fuse94>>24) &0xFF;
|
||||
/* set encryption key */
|
||||
rijndael_set_key(&aes_ctx, kirk16_key, 128);
|
||||
|
||||
@@ -631,18 +623,18 @@ void encrypt_kirk16_private(u8 *dA_out, u8 *dA_dec)
|
||||
AES_cbc_encrypt((AES_ctx *)&aes_ctx, dA_dec, dA_out, 0x20);
|
||||
}
|
||||
|
||||
int kirk_CMD16(u8 * outbuff, int outsize, u8 * inbuff, int insize) {
|
||||
int kirk_CMD16(KirkState *kirk, u8 * outbuff, int outsize, u8 * inbuff, int insize) {
|
||||
u8 dec_private[0x20];
|
||||
KIRK_CMD16_BUFFER * signbuf = (KIRK_CMD16_BUFFER *) inbuff;
|
||||
ECDSA_SIG * sig = (ECDSA_SIG *) outbuff;
|
||||
if(insize != 0x34) return KIRK_INVALID_SIZE;
|
||||
if(outsize != 0x28) return KIRK_INVALID_SIZE;
|
||||
decrypt_kirk16_private(dec_private,signbuf->enc_private);
|
||||
decrypt_kirk16_private(kirk, dec_private,signbuf->enc_private);
|
||||
// Clear out the padding for safety
|
||||
memset(&dec_private[0x14], 0, 0xC);
|
||||
ecdsa_set_curve(ec_p,ec_a,ec_b2,ec_N2,Gx2,Gy2);
|
||||
ecdsa_set_priv(dec_private);
|
||||
ecdsa_sign(signbuf->message_hash,sig->r, sig->s);
|
||||
ecdsa_sign(kirk, signbuf->message_hash,sig->r, sig->s);
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -652,7 +644,7 @@ int kirk_CMD16(u8 * outbuff, int outsize, u8 * inbuff, int insize) {
|
||||
// 28 = message hash (0x14 length)
|
||||
// 3C = signature R (0x14 length)
|
||||
// 50 = signature S (0x14 length)
|
||||
int kirk_CMD17(const u8 * inbuff, int insize) {
|
||||
int kirk_CMD17(KirkState *kirk, const u8 * inbuff, int insize) {
|
||||
KIRK_CMD17_BUFFER * sig = (KIRK_CMD17_BUFFER *) inbuff;
|
||||
if(insize != 0x64) return KIRK_INVALID_SIZE;
|
||||
ecdsa_set_curve(ec_p,ec_a,ec_b2,ec_N2,Gx2,Gy2);
|
||||
@@ -665,18 +657,16 @@ int kirk_CMD17(const u8 * inbuff, int insize) {
|
||||
}
|
||||
}
|
||||
|
||||
int kirk_init()
|
||||
int kirk_init(KirkState *kirk)
|
||||
{
|
||||
return kirk_init2((u8*)"Lazy Dev should have initialized!",33,0xBABEF00D, 0xDEADBEEF );
|
||||
return kirk_init2(kirk, (u8*)"Lazy Dev should have initialized!",33,0xBABEF00D, 0xDEADBEEF );
|
||||
}
|
||||
|
||||
int kirk_init2(u8 * rnd_seed, u32 seed_size, u32 fuseid_90, u32 fuseid_94) {
|
||||
int kirk_init2(KirkState *kirk, u8 * rnd_seed, u32 seed_size, u32 fuseid_90, u32 fuseid_94) {
|
||||
u8 temp[0x104];
|
||||
memset(temp, 0xAA, sizeof(temp));
|
||||
|
||||
KIRK_SHA1_HEADER *header = (KIRK_SHA1_HEADER *) temp;
|
||||
// Another randomly selected data for a "key" to add to each randomization
|
||||
static const u8 key[0x10] = {0x07, 0xAB, 0xEF, 0xF8, 0x96, 0x8C, 0xF3, 0xD6, 0x14, 0xE0, 0xEB, 0xB2, 0x9D, 0x8B, 0x4E, 0x74};
|
||||
u32 curtime;
|
||||
|
||||
//Set PRNG_DATA initially, otherwise use what ever uninitialized data is in the buffer
|
||||
@@ -687,30 +677,30 @@ int kirk_init2(u8 * rnd_seed, u32 seed_size, u32 fuseid_90, u32 fuseid_94) {
|
||||
memset(seedbuf, 0, seed_size+4);
|
||||
seedheader = (KIRK_SHA1_HEADER *) seedbuf;
|
||||
seedheader->data_size = seed_size;
|
||||
kirk_CMD11(PRNG_DATA, seedbuf, seed_size+4);
|
||||
kirk_CMD11(kirk, kirk->PRNG_DATA, seedbuf, seed_size+4);
|
||||
free(seedbuf);
|
||||
}
|
||||
memcpy(temp+4, PRNG_DATA,0x14);
|
||||
memcpy(temp+4, kirk->PRNG_DATA,0x14);
|
||||
// This uses the standard C time function for portability.
|
||||
curtime=(u32)time(0);
|
||||
temp[0x18] = curtime &0xFF;
|
||||
temp[0x19] = (curtime>>8) &0xFF;
|
||||
temp[0x1A] = (curtime>>16) &0xFF;
|
||||
temp[0x1B] = (curtime>>24) &0xFF;
|
||||
memcpy(&temp[0x1C], key, 0x10);
|
||||
memcpy(&temp[0x1C], random_key, 0x10);
|
||||
//This leaves the remainder of the 0x100 bytes in temp to whatever remains on the stack
|
||||
// in an uninitialized state. This should add unpredicableness to the results as well
|
||||
header->data_size=0x100;
|
||||
kirk_CMD11(PRNG_DATA, temp, 0x104);
|
||||
kirk_CMD11(kirk, kirk->PRNG_DATA, temp, 0x104);
|
||||
|
||||
//Set Fuse ID
|
||||
g_fuse90=fuseid_90;
|
||||
g_fuse94=fuseid_94;
|
||||
kirk->g_fuse90=fuseid_90;
|
||||
kirk->g_fuse94=fuseid_94;
|
||||
|
||||
//Set KIRK1 main key
|
||||
AES_set_key(&aes_kirk1, kirk1_key, 128);
|
||||
AES_set_key(&kirk->aes_kirk1, kirk1_key, 128);
|
||||
|
||||
is_kirk_initialized = 1;
|
||||
kirk->is_kirk_initialized = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -719,7 +709,7 @@ const u8* kirk_4_7_get_key(int key_type){
|
||||
return keyvault[key_type];
|
||||
}
|
||||
|
||||
int kirk_CMD1_ex(u8* outbuff, u8* inbuff, int size, KIRK_CMD1_HEADER* header)
|
||||
int kirk_CMD1_ex(KirkState *kirk, u8* outbuff, u8* inbuff, int size, KIRK_CMD1_HEADER* header)
|
||||
{
|
||||
u8* buffer = (u8*)malloc(size);
|
||||
int ret;
|
||||
@@ -727,26 +717,26 @@ int kirk_CMD1_ex(u8* outbuff, u8* inbuff, int size, KIRK_CMD1_HEADER* header)
|
||||
memcpy(buffer, header, sizeof(KIRK_CMD1_HEADER));
|
||||
memcpy(buffer+sizeof(KIRK_CMD1_HEADER), inbuff, header->data_size);
|
||||
|
||||
ret = kirk_CMD1(outbuff, buffer, size);
|
||||
ret = kirk_CMD1(kirk, outbuff, buffer, size);
|
||||
free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kirk_sceUtilsBufferCopyWithRange(u8* outbuff, int outsize, u8* inbuff, int insize, int cmd)
|
||||
int kirk_sceUtilsBufferCopyWithRange(KirkState *kirk, u8* outbuff, int outsize, u8* inbuff, int insize, int cmd)
|
||||
{
|
||||
// TODO: propagate const-correctness into all these functions.
|
||||
switch(cmd)
|
||||
{
|
||||
case KIRK_CMD_DECRYPT_PRIVATE: return kirk_CMD1(outbuff, inbuff, insize); break; // NOTE: I think this actually trashes inbuff
|
||||
case KIRK_CMD_ENCRYPT_IV_0: return kirk_CMD4(outbuff, inbuff, insize); break;
|
||||
case KIRK_CMD_DECRYPT_IV_0: return kirk_CMD7(outbuff, inbuff, insize); break;
|
||||
case KIRK_CMD_PRIV_SIGN_CHECK: return kirk_CMD10(inbuff, insize); break;
|
||||
case KIRK_CMD_SHA1_HASH: return kirk_CMD11(outbuff, inbuff, insize); break;
|
||||
case KIRK_CMD_ECDSA_GEN_KEYS: return kirk_CMD12(outbuff, outsize); break;
|
||||
case KIRK_CMD_ECDSA_MULTIPLY_POINT: return kirk_CMD13(outbuff, outsize, inbuff, insize); break;
|
||||
case KIRK_CMD_PRNG: return kirk_CMD14(outbuff, outsize); break;
|
||||
case KIRK_CMD_ECDSA_SIGN: return kirk_CMD16(outbuff, outsize, inbuff, insize); break;
|
||||
case KIRK_CMD_ECDSA_VERIFY: return kirk_CMD17(inbuff, insize); break;
|
||||
case KIRK_CMD_DECRYPT_PRIVATE: return kirk_CMD1(kirk, outbuff, inbuff, insize); break; // NOTE: I think this actually trashes inbuff
|
||||
case KIRK_CMD_ENCRYPT_IV_0: return kirk_CMD4(kirk, outbuff, inbuff, insize); break;
|
||||
case KIRK_CMD_DECRYPT_IV_0: return kirk_CMD7(kirk, outbuff, inbuff, insize); break;
|
||||
case KIRK_CMD_PRIV_SIGN_CHECK: return kirk_CMD10(kirk, inbuff, insize); break;
|
||||
case KIRK_CMD_SHA1_HASH: return kirk_CMD11(kirk, outbuff, inbuff, insize); break;
|
||||
case KIRK_CMD_ECDSA_GEN_KEYS: return kirk_CMD12(kirk, outbuff, outsize); break;
|
||||
case KIRK_CMD_ECDSA_MULTIPLY_POINT: return kirk_CMD13(kirk, outbuff, outsize, inbuff, insize); break;
|
||||
case KIRK_CMD_PRNG: return kirk_CMD14(kirk, outbuff, outsize); break;
|
||||
case KIRK_CMD_ECDSA_SIGN: return kirk_CMD16(kirk, outbuff, outsize, inbuff, insize); break;
|
||||
case KIRK_CMD_ECDSA_VERIFY: return kirk_CMD17(kirk, inbuff, insize); break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
+41
-23
@@ -24,11 +24,15 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KIRK_ENGINE
|
||||
#define KIRK_ENGINE
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short int u16;
|
||||
typedef unsigned int u32;
|
||||
#pragma once
|
||||
|
||||
#include "kirk_common.h"
|
||||
#include "SHA1.h"
|
||||
#include "AES.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//Kirk return values
|
||||
#define KIRK_OPERATION_SUCCESS 0
|
||||
@@ -191,22 +195,33 @@ typedef struct
|
||||
0x12: Certificate Check (idstorage signatures)
|
||||
*/
|
||||
|
||||
typedef struct KirkState {
|
||||
u32 g_fuse90; // This is to match FuseID HW at BC100090 and BC100094
|
||||
u32 g_fuse94;
|
||||
|
||||
AES_ctx aes_kirk1; //global
|
||||
u8 PRNG_DATA[0x14];
|
||||
u8 kirk_buf[0x0814]; // 1DC0 1DD4
|
||||
|
||||
char is_kirk_initialized; //"init" emulation
|
||||
} KirkState;
|
||||
|
||||
//kirk-like funcs
|
||||
int kirk_CMD0(u8* outbuff, const u8* inbuff, int size, int generate_trash);
|
||||
int kirk_CMD1(u8* outbuff, u8* inbuff, int size);
|
||||
int kirk_CMD0(KirkState *kirk, u8* outbuff, const u8* inbuff, int size, int generate_trash);
|
||||
int kirk_CMD1(KirkState *kirk, u8* outbuff, u8* inbuff, int size);
|
||||
|
||||
int kirk_CMD4(u8* outbuff, const u8* inbuff, int size);
|
||||
int kirk_CMD7(u8* outbuff, const u8* inbuff, int size);
|
||||
int kirk_CMD10(u8* inbuff, int insize);
|
||||
int kirk_CMD11(u8* outbuff, const u8* inbuff, int size);
|
||||
int kirk_CMD12(u8* outbuff, int outsize);
|
||||
int kirk_CMD13(u8* outbuff, int outsize,u8* inbuff, int insize);
|
||||
int kirk_CMD14(u8* outbuff, int outsize);
|
||||
int kirk_CMD16(u8* outbuff, int outsize,u8* inbuff, int insize);
|
||||
int kirk_CMD17(const u8* inbuff, int insize);
|
||||
int kirk_CMD4(KirkState *kirk, u8* outbuff, const u8* inbuff, int size);
|
||||
int kirk_CMD7(KirkState *kirk, u8* outbuff, const u8* inbuff, int size);
|
||||
int kirk_CMD10(KirkState *kirk, u8* inbuff, int insize);
|
||||
int kirk_CMD11(KirkState *kirk, u8* outbuff, const u8* inbuff, int size);
|
||||
int kirk_CMD12(KirkState *kirk, u8* outbuff, int outsize);
|
||||
int kirk_CMD13(KirkState *kirk, u8* outbuff, int outsize,u8* inbuff, int insize);
|
||||
int kirk_CMD14(KirkState *kirk, u8* outbuff, int outsize);
|
||||
int kirk_CMD16(KirkState *kirk, u8* outbuff, int outsize,u8* inbuff, int insize);
|
||||
int kirk_CMD17(KirkState *kirk, const u8* inbuff, int insize);
|
||||
|
||||
int kirk_init(); //CMD 0xF?
|
||||
int kirk_init2(u8 *, u32, u32, u32);
|
||||
int kirk_init(KirkState *kirk); //CMD 0xF?
|
||||
int kirk_init2(KirkState *kirk, u8 *, u32, u32, u32);
|
||||
|
||||
// overhead free functions
|
||||
void kirk4(u8* outbuff, const u8* inbuff, size_t size, int keyId);
|
||||
@@ -216,20 +231,20 @@ void kirk7(u8* outbuff, const u8* inbuff, size_t size, int keyId);
|
||||
const u8* kirk_4_7_get_key(int key_type);
|
||||
|
||||
//kirk "ex" functions
|
||||
int kirk_CMD1_ex(u8* outbuff, u8* inbuff, int size, KIRK_CMD1_HEADER* header);
|
||||
int kirk_CMD1_ex(KirkState *kirk, u8* outbuff, u8* inbuff, int size, KIRK_CMD1_HEADER* header);
|
||||
|
||||
//sce-like func. sceUtilsBufferCopyWithRange is clearly intentionally confusingly named.
|
||||
// Also, some commands do write to inbuff!
|
||||
int kirk_sceUtilsBufferCopyWithRange(u8* outbuff, int outsize, u8* inbuff, int insize, int cmd);
|
||||
void decrypt_kirk16_private(u8 *dA_out, u8 *dA_enc);
|
||||
void encrypt_kirk16_private(u8 *dA_out, u8 *dA_dec);
|
||||
int kirk_sceUtilsBufferCopyWithRange(KirkState *kirk, u8* outbuff, int outsize, u8* inbuff, int insize, int cmd);
|
||||
void decrypt_kirk16_private(KirkState *kirk, u8 *dA_out, u8 *dA_enc);
|
||||
void encrypt_kirk16_private(KirkState *kirk, u8 *dA_out, u8 *dA_dec);
|
||||
|
||||
// Prototypes for the Elliptic Curve and Big Number functions
|
||||
int ecdsa_set_curve(const u8* p, const u8* a, const u8* b, const u8* N, const u8* Gx, const u8* Gy);
|
||||
void ecdsa_set_pub(u8 *Q);
|
||||
void ecdsa_set_priv(u8 *k);
|
||||
int ecdsa_verify(u8 *hash, u8 *R, u8 *S);
|
||||
void ecdsa_sign(u8 *hash, u8 *R, u8 *S);
|
||||
void ecdsa_sign(KirkState *kirk, u8 *hash, u8 *R, u8 *S);
|
||||
void ec_priv_to_pub(u8 *k, u8 *Q);
|
||||
void ec_pub_mult(u8 *k, u8 *Q);
|
||||
|
||||
@@ -247,4 +262,7 @@ void hex_dump(const char *str, const u8 *buf, int size);
|
||||
#define round_up(x,n) (-(-(x) & -(n)))
|
||||
|
||||
#define array_size(x) (sizeof(x) / sizeof(*(x)))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -287,6 +287,7 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="AES.h" />
|
||||
<ClInclude Include="amctrl.h" />
|
||||
<ClInclude Include="kirk_common.h" />
|
||||
<ClInclude Include="kirk_engine.h" />
|
||||
<ClInclude Include="SHA1.h" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
<ClInclude Include="amctrl.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="kirk_common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="CMakeLists.txt" />
|
||||
|
||||
Reference in New Issue
Block a user