diff --git a/CMakeLists.txt b/CMakeLists.txt index e3bf616845..ed768462b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/Core/ELF/PrxDecrypter.cpp b/Core/ELF/PrxDecrypter.cpp index 76ecd829d9..edccbb2597 100644 --- a/Core/ELF/PrxDecrypter.cpp +++ b/Core/ELF/PrxDecrypter.cpp @@ -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(header)+sizeof(KIRK_CMD1_HEADER), type0.prxHeader, sizeof(type0.prxHeader)); decryptKirkHeaderType0(reinterpret_cast(header), type0.kirkBlock, xorbuf, pti->code); - if (kirk_sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0) + if (kirk_sceUtilsBufferCopyWithRange(kirk, outbuf, size, reinterpret_cast(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(header)+sizeof(KIRK_CMD1_HEADER), type1.prxHeader, sizeof(type1.prxHeader)); decryptKirkHeaderType0(reinterpret_cast(header), type1.kirkBlock, xorbuf, pti->code); - if (kirk_sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0) + if (kirk_sceUtilsBufferCopyWithRange(kirk, outbuf, size, reinterpret_cast(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(header), type2.kirkHeader, xorbuf.cbegin()+0x10, pti->code); header->mode = 1; - if (kirk_sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0) + if (kirk_sceUtilsBufferCopyWithRange(kirk, outbuf, size, reinterpret_cast(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(header), type5.kirkHeader, xorbuf.cbegin()+0x10, pti->code); header->mode = 1; - if (kirk_sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0) + if (kirk_sceUtilsBufferCopyWithRange(kirk, outbuf, size, reinterpret_cast(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(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0) + if (kirk_sceUtilsBufferCopyWithRange(kirk, outbuf, size, reinterpret_cast(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); } diff --git a/Core/FileSystems/BlockDevices.cpp b/Core/FileSystems/BlockDevices.cpp index 93ec8969b0..8a6e7dc8ab 100644 --- a/Core/FileSystems/BlockDevices.cpp +++ b/Core/FileSystems/BlockDevices.cpp @@ -381,7 +381,6 @@ bool CISOFileBlockDevice::ReadBlocks(u32 minBlock, int count, u8 *outPtr) { NPDRMDemoBlockDevice::NPDRMDemoBlockDevice(FileLoader *fileLoader) : BlockDevice(fileLoader) { - std::lock_guard 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 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); } diff --git a/Core/FileSystems/BlockDevices.h b/Core/FileSystems/BlockDevices.h index 718c8891a9..aaa985b700 100644 --- a/Core/FileSystems/BlockDevices.h +++ b/Core/FileSystems/BlockDevices.h @@ -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; diff --git a/Core/HLE/sceChnnlsv.cpp b/Core/HLE/sceChnnlsv.cpp index f88941f377..89530b5ff4 100644 --- a/Core/HLE/sceChnnlsv.cpp +++ b/Core/HLE/sceChnnlsv.cpp @@ -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", 'x', "xixii" }, + {0x77E97079, &WrapI_UIUII, "sceUtilsBufferCopyByPollingWithRange", 'i', "xixii" }, +}; + +void Register_semaphore() { + RegisterHLEModule("semaphore", ARRAY_SIZE(semaphore), semaphore); } diff --git a/Core/HLE/sceChnnlsv.h b/Core/HLE/sceChnnlsv.h index d38d574365..2c0f7ceabb 100644 --- a/Core/HLE/sceChnnlsv.h +++ b/Core/HLE/sceChnnlsv.h @@ -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(); diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 0c6136695d..a812e836ea 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -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); diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index 6c78712f38..2b71e4dced 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -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", 'x', "xixii" }, - {0x77E97079, &WrapI_UIUII, "sceUtilsBufferCopyByPollingWithRange", 'i', "xixii" }, -}; - -void Register_semaphore() { - RegisterHLEModule("semaphore", ARRAY_SIZE(semaphore), semaphore); -} diff --git a/Core/HLE/sceKernelSemaphore.h b/Core/HLE/sceKernelSemaphore.h index 0165c0c739..1a635925e6 100644 --- a/Core/HLE/sceKernelSemaphore.h +++ b/Core/HLE/sceKernelSemaphore.h @@ -32,9 +32,7 @@ void __KernelSemaInit(); void __KernelSemaDoState(PointerWrap &p); KernelObject *__KernelSemaphoreObject(); -void Register_semaphore(); - extern "C" { #include "ext/libkirk/kirk_engine.h" -} \ No newline at end of file +} diff --git a/ext/libkirk/AES.h b/ext/libkirk/AES.h index b77cb04cf9..b6474ec4c0 100644 --- a/ext/libkirk/AES.h +++ b/ext/libkirk/AES.h @@ -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) diff --git a/ext/libkirk/SHA1.h b/ext/libkirk/SHA1.h index 39794fa86c..43493e3319 100644 --- a/ext/libkirk/SHA1.h +++ b/ext/libkirk/SHA1.h @@ -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_ */ diff --git a/ext/libkirk/amctrl.c b/ext/libkirk/amctrl.c index 3116c39725..688f7fe1bd 100644 --- a/ext/libkirk/amctrl.c +++ b/ext/libkirk/amctrl.c @@ -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; diff --git a/ext/libkirk/amctrl.h b/ext/libkirk/amctrl.h index e4c9d04aaf..af6dbdcd12 100644 --- a/ext/libkirk/amctrl.h +++ b/ext/libkirk/amctrl.h @@ -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 - diff --git a/ext/libkirk/ec.c b/ext/libkirk/ec.c index 0a4a3317a4..7a4f7118b1 100644 --- a/ext/libkirk/ec.c +++ b/ext/libkirk/ec.c @@ -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) diff --git a/ext/libkirk/kirk_common.h b/ext/libkirk/kirk_common.h new file mode 100644 index 0000000000..c6e54517ab --- /dev/null +++ b/ext/libkirk/kirk_common.h @@ -0,0 +1,6 @@ +#pragma once + +typedef unsigned char u8; +typedef unsigned short int u16; +typedef unsigned int u32; + diff --git a/ext/libkirk/kirk_engine.c b/ext/libkirk/kirk_engine.c index a9deafd771..59e2aff2bd 100644 --- a/ext/libkirk/kirk_engine.c +++ b/ext/libkirk/kirk_engine.c @@ -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; } diff --git a/ext/libkirk/kirk_engine.h b/ext/libkirk/kirk_engine.h index 6dd541cd90..de90c4d48e 100644 --- a/ext/libkirk/kirk_engine.h +++ b/ext/libkirk/kirk_engine.h @@ -24,11 +24,15 @@ along with this program. If not, see . */ -#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 diff --git a/ext/libkirk/libkirk.vcxproj b/ext/libkirk/libkirk.vcxproj index 3d0fcdd8d0..95133ba6aa 100644 --- a/ext/libkirk/libkirk.vcxproj +++ b/ext/libkirk/libkirk.vcxproj @@ -287,6 +287,7 @@ + diff --git a/ext/libkirk/libkirk.vcxproj.filters b/ext/libkirk/libkirk.vcxproj.filters index 82e0df0fa1..6a4c7e765a 100644 --- a/ext/libkirk/libkirk.vcxproj.filters +++ b/ext/libkirk/libkirk.vcxproj.filters @@ -47,6 +47,9 @@ Header Files + + Header Files +