Added ~PSP decryption system using kirk-engine

This commit is contained in:
Arthur Blot 2012-11-05 14:54:28 +01:00
parent ddfbd18370
commit 5b5618d32d
52 changed files with 4465 additions and 40 deletions

View File

@ -13,6 +13,7 @@ set(SRCS
MIPS/MIPSVFPUUtils.cpp
MIPS/JitCommon/JitCommon.cpp
ELF/ElfReader.cpp
ELF/PrxDecrypter.cpp
HLE/HLE.cpp
HLE/HLETables.cpp
HLE/sceAtrac.cpp
@ -97,4 +98,3 @@ if(UNIX)
add_definitions(-fPIC)
add_definitions(-std=gnu++0x)
endif(UNIX)

View File

@ -66,7 +66,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../zlib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
@ -77,7 +77,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../zlib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
@ -90,7 +90,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../zlib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -104,7 +104,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../zlib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -350,11 +350,11 @@
<ProjectReference Include="..\native\native.vcxproj">
<Project>{e8b58922-9827-493d-81e0-4b6e6bd77171}</Project>
</ProjectReference>
<ProjectReference Include="..\zlib\zlib.vcxproj">
<ProjectReference Include="..\ext\zlib\zlib.vcxproj">
<Project>{f761046e-6c38-4428-a5f1-38391a37bb34}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -197,7 +197,7 @@ bool ElfReader::LoadInto(u32 vaddr)
addr += segmentVAddr[readwrite];
u32 op = Memory::ReadUnchecked_U32(addr);
const bool log = false;
//log=true;
if (log)

734
Core/ELF/PrxDecrypter.cpp Normal file
View File

@ -0,0 +1,734 @@
#include <cstring>
extern "C"
{
#include "ext/libkirk/kirk_engine.h"
}
#include "../../Globals.h"
// Thank you PSARDUMPER & JPCSP keys
// PRXDecrypter 16-byte tag keys.
u8 keys260_0[] = {0xC3, 0x24, 0x89, 0xD3, 0x80, 0x87, 0xB2, 0x4E, 0x4C, 0xD7, 0x49, 0xE4, 0x9D, 0x1D, 0x34, 0xD1};
u8 keys260_1[] = {0xF3, 0xAC, 0x6E, 0x7C, 0x04, 0x0A, 0x23, 0xE7, 0x0D, 0x33, 0xD8, 0x24, 0x73, 0x39, 0x2B, 0x4A};
u8 keys260_2[] = {0x72, 0xB4, 0x39, 0xFF, 0x34, 0x9B, 0xAE, 0x82, 0x30, 0x34, 0x4A, 0x1D, 0xA2, 0xD8, 0xB4, 0x3C};
u8 keys280_0[] = {0xCA, 0xFB, 0xBF, 0xC7, 0x50, 0xEA, 0xB4, 0x40, 0x8E, 0x44, 0x5C, 0x63, 0x53, 0xCE, 0x80, 0xB1};
u8 keys280_1[] = {0x40, 0x9B, 0xC6, 0x9B, 0xA9, 0xFB, 0x84, 0x7F, 0x72, 0x21, 0xD2, 0x36, 0x96, 0x55, 0x09, 0x74};
u8 keys280_2[] = {0x03, 0xA7, 0xCC, 0x4A, 0x5B, 0x91, 0xC2, 0x07, 0xFF, 0xFC, 0x26, 0x25, 0x1E, 0x42, 0x4B, 0xB5};
u8 keys300_0[] = {0x9F, 0x67, 0x1A, 0x7A, 0x22, 0xF3, 0x59, 0x0B, 0xAA, 0x6D, 0xA4, 0xC6, 0x8B, 0xD0, 0x03, 0x77};
u8 keys300_1[] = {0x15, 0x07, 0x63, 0x26, 0xDB, 0xE2, 0x69, 0x34, 0x56, 0x08, 0x2A, 0x93, 0x4E, 0x4B, 0x8A, 0xB2};
u8 keys300_2[] = {0x56, 0x3B, 0x69, 0xF7, 0x29, 0x88, 0x2F, 0x4C, 0xDB, 0xD5, 0xDE, 0x80, 0xC6, 0x5C, 0xC8, 0x73};
u8 keys303_0[] = {0x7b, 0xa1, 0xe2, 0x5a, 0x91, 0xb9, 0xd3, 0x13, 0x77, 0x65, 0x4a, 0xb7, 0xc2, 0x8a, 0x10, 0xaf};
u8 keys310_0[] = {0xa2, 0x41, 0xe8, 0x39, 0x66, 0x5b, 0xfa, 0xbb, 0x1b, 0x2d, 0x6e, 0x0e, 0x33, 0xe5, 0xd7, 0x3f};
u8 keys310_1[] = {0xA4, 0x60, 0x8F, 0xAB, 0xAB, 0xDE, 0xA5, 0x65, 0x5D, 0x43, 0x3A, 0xD1, 0x5E, 0xC3, 0xFF, 0xEA};
u8 keys310_2[] = {0xE7, 0x5C, 0x85, 0x7A, 0x59, 0xB4, 0xE3, 0x1D, 0xD0, 0x9E, 0xCE, 0xC2, 0xD6, 0xD4, 0xBD, 0x2B};
u8 keys310_3[] = {0x2E, 0x00, 0xF6, 0xF7, 0x52, 0xCF, 0x95, 0x5A, 0xA1, 0x26, 0xB4, 0x84, 0x9B, 0x58, 0x76, 0x2F};
u8 keys330_0[] = {0x3B, 0x9B, 0x1A, 0x56, 0x21, 0x80, 0x14, 0xED, 0x8E, 0x8B, 0x08, 0x42, 0xFA, 0x2C, 0xDC, 0x3A};
u8 keys330_1[] = {0xE8, 0xBE, 0x2F, 0x06, 0xB1, 0x05, 0x2A, 0xB9, 0x18, 0x18, 0x03, 0xE3, 0xEB, 0x64, 0x7D, 0x26};
u8 keys330_2[] = {0xAB, 0x82, 0x25, 0xD7, 0x43, 0x6F, 0x6C, 0xC1, 0x95, 0xC5, 0xF7, 0xF0, 0x63, 0x73, 0x3F, 0xE7};
u8 keys330_3[] = {0xA8, 0xB1, 0x47, 0x77, 0xDC, 0x49, 0x6A, 0x6F, 0x38, 0x4C, 0x4D, 0x96, 0xBD, 0x49, 0xEC, 0x9B};
u8 keys330_4[] = {0xEC, 0x3B, 0xD2, 0xC0, 0xFA, 0xC1, 0xEE, 0xB9, 0x9A, 0xBC, 0xFF, 0xA3, 0x89, 0xF2, 0x60, 0x1F};
u8 keys360_0[] = {0x3C, 0x2B, 0x51, 0xD4, 0x2D, 0x85, 0x47, 0xDA, 0x2D, 0xCA, 0x18, 0xDF, 0xFE, 0x54, 0x09, 0xED};
u8 keys360_1[] = {0x31, 0x1F, 0x98, 0xD5, 0x7B, 0x58, 0x95, 0x45, 0x32, 0xAB, 0x3A, 0xE3, 0x89, 0x32, 0x4B, 0x34};
u8 keys370_0[] = {0x26, 0x38, 0x0A, 0xAC, 0xA5, 0xD8, 0x74, 0xD1, 0x32, 0xB7, 0x2A, 0xBF, 0x79, 0x9E, 0x6D, 0xDB};
u8 keys370_1[] = {0x53, 0xE7, 0xAB, 0xB9, 0xC6, 0x4A, 0x4B, 0x77, 0x92, 0x17, 0xB5, 0x74, 0x0A, 0xDA, 0xA9, 0xEA};
u8 keys370_2[] = {0x71, 0x10, 0xF0, 0xA4, 0x16, 0x14, 0xD5, 0x93, 0x12, 0xFF, 0x74, 0x96, 0xDF, 0x1F, 0xDA, 0x89};
u8 keys390_0[] = {0x45, 0xEF, 0x5C, 0x5D, 0xED, 0x81, 0x99, 0x84, 0x12, 0x94, 0x8F, 0xAB, 0xE8, 0x05, 0x6D, 0x7D};
u8 keys390_1[] = {0x70, 0x1B, 0x08, 0x25, 0x22, 0xA1, 0x4D, 0x3B, 0x69, 0x21, 0xF9, 0x71, 0x0A, 0xA8, 0x41, 0xA9};
u8 keys500_0[] = {0xEB, 0x1B, 0x53, 0x0B, 0x62, 0x49, 0x32, 0x58, 0x1F, 0x83, 0x0A, 0xF4, 0x99, 0x3D, 0x75, 0xD0};
u8 keys500_1[] = {0xBA, 0xE2, 0xA3, 0x12, 0x07, 0xFF, 0x04, 0x1B, 0x64, 0xA5, 0x11, 0x85, 0xF7, 0x2F, 0x99, 0x5B};
u8 keys500_2[] = {0x2C, 0x8E, 0xAF, 0x1D, 0xFF, 0x79, 0x73, 0x1A, 0xAD, 0x96, 0xAB, 0x09, 0xEA, 0x35, 0x59, 0x8B};
u8 keys500_c[] = {0xA3, 0x5D, 0x51, 0xE6, 0x56, 0xC8, 0x01, 0xCA, 0xE3, 0x77, 0xBF, 0xCD, 0xFF, 0x24, 0xDA, 0x4D};
u8 keys505_a[] = {0x7B, 0x94, 0x72, 0x27, 0x4C, 0xCC, 0x54, 0x3B, 0xAE, 0xDF, 0x46, 0x37, 0xAC, 0x01, 0x4D, 0x87};
u8 keys505_0[] = {0x2E, 0x8E, 0x97, 0xA2, 0x85, 0x42, 0x70, 0x73, 0x18, 0xDA, 0xA0, 0x8A, 0xF8, 0x62, 0xA2, 0xB0};
u8 keys505_1[] = {0x58, 0x2A, 0x4C, 0x69, 0x19, 0x7B, 0x83, 0x3D, 0xD2, 0x61, 0x61, 0xFE, 0x14, 0xEE, 0xAA, 0x11};
u8 keys570_5k[] = {0x6D, 0x72, 0xA4, 0xBA, 0x7F, 0xBF, 0xD1, 0xF1, 0xA9, 0xF3, 0xBB, 0x07, 0x1B, 0xC0, 0xB3, 0x66};
u8 keys600_1[] = {0xE3, 0x52, 0x39, 0x97, 0x3B, 0x84, 0x41, 0x1C, 0xC3, 0x23, 0xF1, 0xB8, 0xA9, 0x09, 0x4B, 0xF0};
u8 keys600_2[] = {0xE1, 0x45, 0x93, 0x2C, 0x53, 0xE2, 0xAB, 0x06, 0x6F, 0xB6, 0x8F, 0x0B, 0x66, 0x91, 0xE7, 0x1E};
u8 keys620_0[] = {0xD6, 0xBD, 0xCE, 0x1E, 0x12, 0xAF, 0x9A, 0xE6, 0x69, 0x30, 0xDE, 0xDA, 0x88, 0xB8, 0xFF, 0xFB};
u8 keys620_1[] = {0x1D, 0x13, 0xE9, 0x50, 0x04, 0x73, 0x3D, 0xD2, 0xE1, 0xDA, 0xB9, 0xC1, 0xE6, 0x7B, 0x25, 0xA7};
u8 keys620_a[] = {0xAC, 0x34, 0xBA, 0xB1, 0x97, 0x8D, 0xAE, 0x6F, 0xBA, 0xE8, 0xB1, 0xD6, 0xDF, 0xDF, 0xF1, 0xA2};
u8 keys620_e[] = {0xB1, 0xB3, 0x7F, 0x76, 0xC3, 0xFB, 0x88, 0xE6, 0xF8, 0x60, 0xD3, 0x35, 0x3C, 0xA3, 0x4E, 0xF3};
u8 keys620_5[] = {0xF1, 0xBC, 0x17, 0x07, 0xAE, 0xB7, 0xC8, 0x30, 0xD8, 0x34, 0x9D, 0x40, 0x6A, 0x8E, 0xDF, 0x4E};
u8 keys620_5k[] = {0x41, 0x8A, 0x35, 0x4F, 0x69, 0x3A, 0xDF, 0x04, 0xFD, 0x39, 0x46, 0xA2, 0x5C, 0x2D, 0xF2, 0x21};
u8 keys620_5v[] = {0xF2, 0x8F, 0x75, 0xA7, 0x31, 0x91, 0xCE, 0x9E, 0x75, 0xBD, 0x27, 0x26, 0xB4, 0xB4, 0x0C, 0x32};
u8 keys630_k1[] = {0x36, 0xB0, 0xDC, 0xFC, 0x59, 0x2A, 0x95, 0x1D, 0x80, 0x2D, 0x80, 0x3F, 0xCD, 0x30, 0xA0, 0x1B};
u8 keys630_k2[] = {0xd4, 0x35, 0x18, 0x02, 0x29, 0x68, 0xfb, 0xa0, 0x6a, 0xa9, 0xa5, 0xed, 0x78, 0xfd, 0x2e, 0x9d};
u8 keys630_k3[] = {0x23, 0x8D, 0x3D, 0xAE, 0x41, 0x50, 0xA0, 0xFA, 0xF3, 0x2F, 0x32, 0xCE, 0xC7, 0x27, 0xCD, 0x50};
u8 keys630_k4[] = {0xAA, 0xA1, 0xB5, 0x7C, 0x93, 0x5A, 0x95, 0xBD, 0xEF, 0x69, 0x16, 0xFC, 0x2B, 0x92, 0x31, 0xDD};
u8 keys630_k5[] = {0x87, 0x37, 0x21, 0xCC, 0x65, 0xAE, 0xAA, 0x5F, 0x40, 0xF6, 0x6F, 0x2A, 0x86, 0xC7, 0xA1, 0xC8};
u8 keys630_k6[] = {0x8D, 0xDB, 0xDC, 0x5C, 0xF2, 0x70, 0x2B, 0x40, 0xB2, 0x3D, 0x00, 0x09, 0x61, 0x7C, 0x10, 0x60};
u8 keys630_k7[] = {0x77, 0x1C, 0x06, 0x5F, 0x53, 0xEC, 0x3F, 0xFC, 0x22, 0xCE, 0x5A, 0x27, 0xFF, 0x78, 0xA8, 0x48};
u8 keys630_k8[] = {0x81, 0xD1, 0x12, 0x89, 0x35, 0xC8, 0xEA, 0x8B, 0xE0, 0x02, 0x2D, 0x2D, 0x6A, 0x18, 0x67, 0xB8};
u8 keys636_k1[] = {0x07, 0xE3, 0x08, 0x64, 0x7F, 0x60, 0xA3, 0x36, 0x6A, 0x76, 0x21, 0x44, 0xC9, 0xD7, 0x06, 0x83};
u8 keys636_k2[] = {0x91, 0xF2, 0x02, 0x9E, 0x63, 0x32, 0x30, 0xA9, 0x1D, 0xDA, 0x0B, 0xA8, 0xB7, 0x41, 0xA3, 0xCC};
u8 keys638_k4[] = {0x98, 0x43, 0xFF, 0x85, 0x68, 0xB2, 0xDB, 0x3B, 0xD4, 0x22, 0xD0, 0x4F, 0xAB, 0x5F, 0x0A, 0x31};
u8 keys639_k3[] = {0x01, 0x7B, 0xF0, 0xE9, 0xBE, 0x9A, 0xDD, 0x54, 0x37, 0xEA, 0x0E, 0xC4, 0xD6, 0x4D, 0x8E, 0x9E};
u8 keys660_k1[] = {0x76, 0xF2, 0x6C, 0x0A, 0xCA, 0x3A, 0xBA, 0x4E, 0xAC, 0x76, 0xD2, 0x40, 0xF5, 0xC3, 0xBF, 0xF9};
u8 keys660_k2[] = {0x7A, 0x3E, 0x55, 0x75, 0xB9, 0x6A, 0xFC, 0x4F, 0x3E, 0xE3, 0xDF, 0xB3, 0x6C, 0xE8, 0x2A, 0x82};
u8 keys660_k3[] = {0xFA, 0x79, 0x09, 0x36, 0xE6, 0x19, 0xE8, 0xA4, 0xA9, 0x41, 0x37, 0x18, 0x81, 0x02, 0xE9, 0xB3};
u8 keys660_v1[] = {0xBA, 0x76, 0x61, 0x47, 0x8B, 0x55, 0xA8, 0x72, 0x89, 0x15, 0x79, 0x6D, 0xD7, 0x2F, 0x78, 0x0E};
u8 keys660_v2[] = {0xF9, 0x4A, 0x6B, 0x96, 0x79, 0x3F, 0xEE, 0x0A, 0x04, 0xC8, 0x8D, 0x7E, 0x5F, 0x38, 0x3A, 0xCF};
u8 keys660_v3[] = {0x88, 0xAF, 0x18, 0xE9, 0xC3, 0xAA, 0x6B, 0x56, 0xF7, 0xC5, 0xA8, 0xBF, 0x1A, 0x84, 0xE9, 0xF3};
u8 keys660_v4[] = {0xD1, 0xB0, 0xAE, 0xC3, 0x24, 0x36, 0x13, 0x49, 0xD6, 0x49, 0xD7, 0x88, 0xEA, 0xA4, 0x99, 0x86};
u8 keys660_v5[] = {0xCB, 0x93, 0x12, 0x38, 0x31, 0xC0, 0x2D, 0x2E, 0x7A, 0x18, 0x5C, 0xAC, 0x92, 0x93, 0xAB, 0x32};
u8 keys660_v6[] = {0x92, 0x8C, 0xA4, 0x12, 0xD6, 0x5C, 0x55, 0x31, 0x5B, 0x94, 0x23, 0x9B, 0x62, 0xB3, 0xDB, 0x47};
u8 keys660_k4[] = {0xC8, 0xA0, 0x70, 0x98, 0xAE, 0xE6, 0x2B, 0x80, 0xD7, 0x91, 0xE6, 0xCA, 0x4C, 0xA9, 0x78, 0x4E};
u8 keys660_k5[] = {0xBF, 0xF8, 0x34, 0x02, 0x84, 0x47, 0xBD, 0x87, 0x1C, 0x52, 0x03, 0x23, 0x79, 0xBB, 0x59, 0x81};
u8 keys660_k6[] = {0xD2, 0x83, 0xCC, 0x63, 0xBB, 0x10, 0x15, 0xE7, 0x7B, 0xC0, 0x6D, 0xEE, 0x34, 0x9E, 0x4A, 0xFA};
u8 keys660_k7[] = {0xEB, 0xD9, 0x1E, 0x05, 0x3C, 0xAE, 0xAB, 0x62, 0xE3, 0xB7, 0x1F, 0x37, 0xE5, 0xCD, 0x68, 0xC3};
u8 keys660_v7[] = {0xC5, 0x9C, 0x77, 0x9C, 0x41, 0x01, 0xE4, 0x85, 0x79, 0xC8, 0x71, 0x63, 0xA5, 0x7D, 0x4F, 0xFB};
u8 keys660_v8[] = {0x86, 0xA0, 0x7D, 0x4D, 0xB3, 0x6B, 0xA2, 0xFD, 0xF4, 0x15, 0x85, 0x70, 0x2D, 0x6A, 0x0D, 0x3A};
u8 keys660_k8[] = {0x85, 0x93, 0x1F, 0xED, 0x2C, 0x4D, 0xA4, 0x53, 0x59, 0x9C, 0x3F, 0x16, 0xF3, 0x50, 0xDE, 0x46};
u8 key_21C0[] = {0x6A, 0x19, 0x71, 0xF3, 0x18, 0xDE, 0xD3, 0xA2, 0x6D, 0x3B, 0xDE, 0xC7, 0xBE, 0x98, 0xE2, 0x4C};
u8 key_2250[] = {0x50, 0xCC, 0x03, 0xAC, 0x3F, 0x53, 0x1A, 0xFA, 0x0A, 0xA4, 0x34, 0x23, 0x86, 0x61, 0x7F, 0x97};
u8 key_22E0[] = {0x66, 0x0F, 0xCB, 0x3B, 0x30, 0x75, 0xE3, 0x10, 0x0A, 0x95, 0x65, 0xC7, 0x3C, 0x93, 0x87, 0x22};
u8 key_2D80[] = {0x40, 0x02, 0xC0, 0xBF, 0x20, 0x02, 0xC0, 0xBF, 0x5C, 0x68, 0x2B, 0x95, 0x5F, 0x40, 0x7B, 0xB8};
u8 key_2D90[] = {0x55, 0x19, 0x35, 0x10, 0x48, 0xD8, 0x2E, 0x46, 0xA8, 0xB1, 0x47, 0x77, 0xDC, 0x49, 0x6A, 0x6F};
u8 key_2DA8[] = {0x80, 0x02, 0xC0, 0xBF, 0x00, 0x0A, 0xC0, 0xBF, 0x40, 0x03, 0xC0, 0xBF, 0x40, 0x00, 0x00, 0x00};
u8 key_2DB8[] = {0x4C, 0x2D, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xB8, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
u8 key_D91605F0[] = {0xB8, 0x8C, 0x45, 0x8B, 0xB6, 0xE7, 0x6E, 0xB8, 0x51, 0x59, 0xA6, 0x53, 0x7C, 0x5E, 0x86, 0x31};
u8 key_D91606F0[] = {0xED, 0x10, 0xE0, 0x36, 0xC4, 0xFE, 0x83, 0xF3, 0x75, 0x70, 0x5E, 0xF6, 0xA4, 0x40, 0x05, 0xF7};
u8 key_D91608F0[] = {0x5C, 0x77, 0x0C, 0xBB, 0xB4, 0xC2, 0x4F, 0xA2, 0x7E, 0x3B, 0x4E, 0xB4, 0xB4, 0xC8, 0x70, 0xAF};
u8 key_D91609F0[] = {0xD0, 0x36, 0x12, 0x75, 0x80, 0x56, 0x20, 0x43, 0xC4, 0x30, 0x94, 0x3E, 0x1C, 0x75, 0xD1, 0xBF};
u8 key_D9160AF0[] = {0x10, 0xA9, 0xAC, 0x16, 0xAE, 0x19, 0xC0, 0x7E, 0x3B, 0x60, 0x77, 0x86, 0x01, 0x6F, 0xF2, 0x63};
u8 key_D9160BF0[] = {0x83, 0x83, 0xF1, 0x37, 0x53, 0xD0, 0xBE, 0xFC, 0x8D, 0xA7, 0x32, 0x52, 0x46, 0x0A, 0xC2, 0xC2};
u8 key_D91611F0[] = {0x61, 0xB0, 0xC0, 0x58, 0x71, 0x57, 0xD9, 0xFA, 0x74, 0x67, 0x0E, 0x5C, 0x7E, 0x6E, 0x95, 0xB9};
u8 key_D91612F0[] = {0x9E, 0x20, 0xE1, 0xCD, 0xD7, 0x88, 0xDE, 0xC0, 0x31, 0x9B, 0x10, 0xAF, 0xC5, 0xB8, 0x73, 0x23};
u8 key_D91613F0[] = {0xEB, 0xFF, 0x40, 0xD8, 0xB4, 0x1A, 0xE1, 0x66, 0x91, 0x3B, 0x8F, 0x64, 0xB6, 0xFC, 0xB7, 0x12};
u8 key_D91614F0[] = {0xFD, 0xF7, 0xB7, 0x3C, 0x9F, 0xD1, 0x33, 0x95, 0x11, 0xB8, 0xB5, 0xBB, 0x54, 0x23, 0x73, 0x85};
u8 key_D91615F0[] = {0xC8, 0x03, 0xE3, 0x44, 0x50, 0xF1, 0xE7, 0x2A, 0x6A, 0x0D, 0xC3, 0x61, 0xB6, 0x8E, 0x5F, 0x51};
u8 key_D91616F0[] = {0x53, 0x03, 0xB8, 0x6A, 0x10, 0x19, 0x98, 0x49, 0x1C, 0xAF, 0x30, 0xE4, 0x25, 0x1B, 0x6B, 0x28};
u8 key_D91617F0[] = {0x02, 0xFA, 0x48, 0x73, 0x75, 0xAF, 0xAE, 0x0A, 0x67, 0x89, 0x2B, 0x95, 0x4B, 0x09, 0x87, 0xA3};
u8 key_D91618F0[] = {0x96, 0x96, 0x7C, 0xC3, 0xF7, 0x12, 0xDA, 0x62, 0x1B, 0xF6, 0x9A, 0x9A, 0x44, 0x44, 0xBC, 0x48};
u8 key_D91619F0[] = {0xE0, 0x32, 0xA7, 0x08, 0x6B, 0x2B, 0x29, 0x2C, 0xD1, 0x4D, 0x5B, 0xEE, 0xA8, 0xC8, 0xB4, 0xE9};
u8 key_D9161AF0[] = {0x27, 0xE5, 0xA7, 0x49, 0x52, 0xE1, 0x94, 0x67, 0x35, 0x66, 0x91, 0x0C, 0xE8, 0x9A, 0x25, 0x24};
u8 key_D91620F0[] = {0x52, 0x1C, 0xB4, 0x5F, 0x40, 0x3B, 0x9A, 0xDD, 0xAC, 0xFC, 0xEA, 0x92, 0xFD, 0xDD, 0xF5, 0x90};
u8 key_D91621F0[] = {0xD1, 0x91, 0x2E, 0xA6, 0x21, 0x14, 0x29, 0x62, 0xF6, 0xED, 0xAE, 0xCB, 0xDD, 0xA3, 0xBA, 0xFE};
u8 key_D91622F0[] = {0x59, 0x5D, 0x78, 0x4D, 0x21, 0xB2, 0x01, 0x17, 0x6C, 0x9A, 0xB5, 0x1B, 0xDA, 0xB7, 0xF9, 0xE6};
u8 key_D91623F0[] = {0xAA, 0x45, 0xEB, 0x4F, 0x62, 0xFB, 0xD1, 0x0D, 0x71, 0xD5, 0x62, 0xD2, 0xF5, 0xBF, 0xA5, 0x2F};
u8 key_D91624F0[] = {0x61, 0xB7, 0x26, 0xAF, 0x8B, 0xF1, 0x41, 0x58, 0x83, 0x6A, 0xC4, 0x92, 0x12, 0xCB, 0xB1, 0xE9};
u8 key_D91628F0[] = {0x49, 0xA4, 0xFC, 0x66, 0xDC, 0xE7, 0x62, 0x21, 0xDB, 0x18, 0xA7, 0x50, 0xD6, 0xA8, 0xC1, 0xB6};
u8 key_D91680F0[] = {0x2C, 0x22, 0x9B, 0x12, 0x36, 0x74, 0x11, 0x67, 0x49, 0xD1, 0xD1, 0x88, 0x92, 0xF6, 0xA1, 0xD8};
u8 key_D91681F0[] = {0x52, 0xB6, 0x36, 0x6C, 0x8C, 0x46, 0x7F, 0x7A, 0xCC, 0x11, 0x62, 0x99, 0xC1, 0x99, 0xBE, 0x98};
u8 key_2E5E10F0[] = {0x9D, 0x5C, 0x5B, 0xAF, 0x8C, 0xD8, 0x69, 0x7E, 0x51, 0x9F, 0x70, 0x96, 0xE6, 0xD5, 0xC4, 0xE8};
u8 key_2E5E12F0[] = {0x8A, 0x7B, 0xC9, 0xD6, 0x52, 0x58, 0x88, 0xEA, 0x51, 0x83, 0x60, 0xCA, 0x16, 0x79, 0xE2, 0x07};
u8 key_2E5E13F0[] = {0xFF, 0xA4, 0x68, 0xC3, 0x31, 0xCA, 0xB7, 0x4C, 0xF1, 0x23, 0xFF, 0x01, 0x65, 0x3D, 0x26, 0x36};
u8 key_2FD30BF0[] = {0xD8, 0x58, 0x79, 0xF9, 0xA4, 0x22, 0xAF, 0x86, 0x90, 0xAC, 0xDA, 0x45, 0xCE, 0x60, 0x40, 0x3F};
u8 key_2FD311F0[] = {0x3A, 0x6B, 0x48, 0x96, 0x86, 0xA5, 0xC8, 0x80, 0x69, 0x6C, 0xE6, 0x4B, 0xF6, 0x04, 0x17, 0x44};
u8 key_2FD312F0[] = {0xC5, 0xFB, 0x69, 0x03, 0x20, 0x7A, 0xCF, 0xBA, 0x2C, 0x90, 0xF8, 0xB8, 0x4D, 0xD2, 0xF1, 0xDE};
u8 keys02G_E[] = {0x9D, 0x09, 0xFD, 0x20, 0xF3, 0x8F, 0x10, 0x69, 0x0D, 0xB2, 0x6F, 0x00, 0xCC, 0xC5, 0x51, 0x2E};
u8 keys03G_E[] = {0x4F, 0x44, 0x5C, 0x62, 0xB3, 0x53, 0xC4, 0x30, 0xFC, 0x3A, 0xA4, 0x5B, 0xEC, 0xFE, 0x51, 0xEA};
u8 keys05G_E[] = {0x5D, 0xAA, 0x72, 0xF2, 0x26, 0x60, 0x4D, 0x1C, 0xE7, 0x2D, 0xC8, 0xA3, 0x2F, 0x79, 0xC5, 0x54};
u8 oneseg_310[] = {0xC7, 0x27, 0x72, 0x85, 0xAB, 0xA7, 0xF7, 0xF0, 0x4C, 0xC1, 0x86, 0xCC, 0xE3, 0x7F, 0x17, 0xCA};
u8 oneseg_300[] = {0x76, 0x40, 0x9E, 0x08, 0xDB, 0x9B, 0x3B, 0xA1, 0x47, 0x8A, 0x96, 0x8E, 0xF3, 0xF7, 0x62, 0x92};
u8 oneseg_280[] = {0x23, 0xDC, 0x3B, 0xB5, 0xA9, 0x82, 0xD6, 0xEA, 0x63, 0xA3, 0x6E, 0x2B, 0x2B, 0xE9, 0xE1, 0x54};
u8 oneseg_260_271[] = {0x22, 0x43, 0x57, 0x68, 0x2F, 0x41, 0xCE, 0x65, 0x4C, 0xA3, 0x7C, 0xC6, 0xC4, 0xAC, 0xF3, 0x60};
u8 oneseg_slim[] = {0x12, 0x57, 0x0D, 0x8A, 0x16, 0x6D, 0x87, 0x06, 0x03, 0x7D, 0xC8, 0x8B, 0x62, 0xA3, 0x32, 0xA9};
u8 ms_app_main[] = {0x1E, 0x2E, 0x38, 0x49, 0xDA, 0xD4, 0x16, 0x08, 0x27, 0x2E, 0xF3, 0xBC, 0x37, 0x75, 0x80, 0x93};
u8 demokeys_280[] = {0x12, 0x99, 0x70, 0x5E, 0x24, 0x07, 0x6C, 0xD0, 0x2D, 0x06, 0xFE, 0x7E, 0xB3, 0x0C, 0x11, 0x26};
u8 demokeys_3XX_1[] = {0x47, 0x05, 0xD5, 0xE3, 0x56, 0x1E, 0x81, 0x9B, 0x09, 0x2F, 0x06, 0xDB, 0x6B, 0x12, 0x92, 0xE0};
u8 demokeys_3XX_2[] = {0xF6, 0x62, 0x39, 0x6E, 0x26, 0x22, 0x4D, 0xCA, 0x02, 0x64, 0x16, 0x99, 0x7B, 0x9A, 0xE7, 0xB8};
u8 ebootbin_271_new[] = {0xF4, 0xAE, 0xF4, 0xE1, 0x86, 0xDD, 0xD2, 0x9C, 0x7C, 0xC5, 0x42, 0xA6, 0x95, 0xA0, 0x83, 0x88};
u8 ebootbin_280_new[] = {0xB8, 0x8C, 0x45, 0x8B, 0xB6, 0xE7, 0x6E, 0xB8, 0x51, 0x59, 0xA6, 0x53, 0x7C, 0x5E, 0x86, 0x31};
u8 ebootbin_300_new[] = {0xED, 0x10, 0xE0, 0x36, 0xC4, 0xFE, 0x83, 0xF3, 0x75, 0x70, 0x5E, 0xF6, 0xA4, 0x40, 0x05, 0xF7};
u8 ebootbin_310_new[] = {0x5C, 0x77, 0x0C, 0xBB, 0xB4, 0xC2, 0x4F, 0xA2, 0x7E, 0x3B, 0x4E, 0xB4, 0xB4, 0xC8, 0x70, 0xAF};
u8 gameshare_260_271[] = {0xF9, 0x48, 0x38, 0x0C, 0x96, 0x88, 0xA7, 0x74, 0x4F, 0x65, 0xA0, 0x54, 0xC2, 0x76, 0xD9, 0xB8};
u8 gameshare_280[] = {0x2D, 0x86, 0x77, 0x3A, 0x56, 0xA4, 0x4F, 0xDD, 0x3C, 0x16, 0x71, 0x93, 0xAA, 0x8E, 0x11, 0x43};
u8 gameshare_300[] = {0x78, 0x1A, 0xD2, 0x87, 0x24, 0xBD, 0xA2, 0x96, 0x18, 0x3F, 0x89, 0x36, 0x72, 0x90, 0x92, 0x85};
u8 gameshare_310[] = {0xC9, 0x7D, 0x3E, 0x0A, 0x54, 0x81, 0x6E, 0xC7, 0x13, 0x74, 0x99, 0x74, 0x62, 0x18, 0xE7, 0xDD};
u8 key_380210F0[] = {0x32, 0x2C, 0xFA, 0x75, 0xE4, 0x7E, 0x93, 0xEB, 0x9F, 0x22, 0x80, 0x85, 0x57, 0x08, 0x98, 0x48};
u8 key_380280F0[] = {0x97, 0x09, 0x12, 0xD3, 0xDB, 0x02, 0xBD, 0xD8, 0xE7, 0x74, 0x51, 0xFE, 0xF0, 0xEA, 0x6C, 0x5C};
u8 key_380283F0[] = {0x34, 0x20, 0x0C, 0x8E, 0xA1, 0x86, 0x79, 0x84, 0xAF, 0x13, 0xAE, 0x34, 0x77, 0x6F, 0xEA, 0x89};
u8 key_407810F0[] = {0xAF, 0xAD, 0xCA, 0xF1, 0x95, 0x59, 0x91, 0xEC, 0x1B, 0x27, 0xD0, 0x4E, 0x8A, 0xF3, 0x3D, 0xE7};
u8 drmkeys_6XX_1[] = {0x36, 0xEF, 0x82, 0x4E, 0x74, 0xFB, 0x17, 0x5B, 0x14, 0x14, 0x05, 0xF3, 0xB3, 0x8A, 0x76, 0x18};
u8 drmkeys_6XX_2[] = {0x21, 0x52, 0x5D, 0x76, 0xF6, 0x81, 0x0F, 0x15, 0x2F, 0x4A, 0x40, 0x89, 0x63, 0xA0, 0x10, 0x55};
// PRXDecrypter 144-byte tag keys.
u32 g_key0[] = {
0x7b21f3be, 0x299c5e1d, 0x1c9c5e71, 0x96cb4645, 0x3c9b1be0, 0xeb85de3d,
0x4a7f2022, 0xc2206eaa, 0xd50b3265, 0x55770567, 0x3c080840, 0x981d55f2,
0x5fd8f6f3, 0xee8eb0c5, 0x944d8152, 0xf8278651, 0x2705bafa, 0x8420e533,
0x27154ae9, 0x4819aa32, 0x59a3aa40, 0x2cb3cf65, 0xf274466d, 0x3a655605,
0x21b0f88f, 0xc5b18d26, 0x64c19051, 0xd669c94e, 0xe87035f2, 0x9d3a5909,
0x6f4e7102, 0xdca946ce, 0x8416881b, 0xbab097a5, 0x249125c6, 0xb34c0872};
u32 g_key2[] = {
0xccfda932, 0x51c06f76, 0x046dcccf, 0x49e1821e, 0x7d3b024c, 0x9dda5865,
0xcc8c9825, 0xd1e97db5, 0x6874d8cb, 0x3471c987, 0x72edb3fc, 0x81c8365d,
0xe161e33a, 0xfc92db59, 0x2009b1ec, 0xb1a94ce4, 0x2f03696b, 0x87e236d8,
0x3b2b8ce9, 0x0305e784, 0xf9710883, 0xb039db39, 0x893bea37, 0xe74d6805,
0x2a5c38bd, 0xb08dc813, 0x15b32375, 0x46be4525, 0x0103fd90, 0xa90e87a2,
0x52aba66a, 0x85bf7b80, 0x45e8ce63, 0x4dd716d3, 0xf5e30d2d, 0xaf3ae456};
u32 g_key3[] = {
0xa6c8f5ca, 0x6d67c080, 0x924f4d3a, 0x047ca06a, 0x08640297, 0x4fd4a758,
0xbd685a87, 0x9b2701c2, 0x83b62a35, 0x726b533c, 0xe522fa0c, 0xc24b06b4,
0x459d1cac, 0xa8c5417b, 0x4fea62a2, 0x0615d742, 0x30628d09, 0xc44fab14,
0x69ff715e, 0xd2d8837d, 0xbeed0b8b, 0x1e6e57ae, 0x61e8c402, 0xbe367a06,
0x543f2b5e, 0xdb3ec058, 0xbe852075, 0x1e7e4dcc, 0x1564ea55, 0xec7825b4,
0xc0538cad, 0x70f72c7f, 0x49e8c3d0, 0xeda97ec5, 0xf492b0a4, 0xe05eb02a};
u32 g_key44[] = {
0xef80e005, 0x3a54689f, 0x43c99ccd, 0x1b7727be, 0x5cb80038, 0xdd2efe62,
0xf369f92c, 0x160f94c5, 0x29560019, 0xbf3c10c5, 0xf2ce5566, 0xcea2c626,
0xb601816f, 0x64e7481e, 0x0c34debd, 0x98f29cb0, 0x3fc504d7, 0xc8fb39f0,
0x0221b3d8, 0x63f936a2, 0x9a3a4800, 0x6ecc32e3, 0x8e120cfd, 0xb0361623,
0xaee1e689, 0x745502eb, 0xe4a6c61c, 0x74f23eb4, 0xd7fa5813, 0xb01916eb,
0x12328457, 0xd2bc97d2, 0x646425d8, 0x328380a5, 0x43da8ab1, 0x4b122ac9};
u32 g_key20[] = {
0x33b50800, 0xf32f5fcd, 0x3c14881f, 0x6e8a2a95, 0x29feefd5, 0x1394eae3,
0xbd6bd443, 0x0821c083, 0xfab379d3, 0xe613e165, 0xf5a754d3, 0x108b2952,
0x0a4b1e15, 0x61eadeba, 0x557565df, 0x3b465301, 0xae54ecc3, 0x61423309,
0x70c9ff19, 0x5b0ae5ec, 0x989df126, 0x9d987a5f, 0x55bc750e, 0xc66eba27,
0x2de988e8, 0xf76600da, 0x0382dccb, 0x5569f5f2, 0x8e431262, 0x288fe3d3,
0x656f2187, 0x37d12e9c, 0x2f539eb4, 0xa492998e, 0xed3958f7, 0x39e96523};
u32 g_key3A[] = {
0x67877069, 0x3abd5617, 0xc23ab1dc, 0xab57507d, 0x066a7f40, 0x24def9b9,
0x06f759e4, 0xdcf524b1, 0x13793e5e, 0x0359022d, 0xaae7e1a2, 0x76b9b2fa,
0x9a160340, 0x87822fba, 0x19e28fbb, 0x9e338a02, 0xd8007e9a, 0xea317af1,
0x630671de, 0x0b67ca7c, 0x865192af, 0xea3c3526, 0x2b448c8e, 0x8b599254,
0x4602e9cb, 0x4de16cda, 0xe164d5bb, 0x07ecd88e, 0x99ffe5f8, 0x768800c1,
0x53b091ed, 0x84047434, 0xb426dbbc, 0x36f948bb, 0x46142158, 0x749bb492};
u32 g_keyEBOOT1xx[] = {
0x18CB69EF, 0x158E8912, 0xDEF90EBB, 0x4CB0FB23, 0x3687EE18, 0x868D4A6E,
0x19B5C756, 0xEE16551D, 0xE7CB2D6C, 0x9747C660, 0xCE95143F, 0x2956F477,
0x03824ADE, 0x210C9DF1, 0x5029EB24, 0x81DFE69F, 0x39C89B00, 0xB00C8B91,
0xEF2DF9C2, 0xE13A93FC, 0x8B94A4A8, 0x491DD09D, 0x686A400D, 0xCED4C7E4,
0x96C8B7C9, 0x1EAADC28, 0xA4170B84, 0x505D5DDC, 0x5DA6C3CF, 0x0E5DFA2D,
0x6E7919B5, 0xCE5E29C7, 0xAAACDB94, 0x45F70CDD, 0x62A73725, 0xCCE6563D};
u32 g_keyEBOOT2xx[] = {
0xDA8E36FA, 0x5DD97447, 0x76C19874, 0x97E57EAF, 0x1CAB09BD, 0x9835BAC6,
0x03D39281, 0x03B205CF, 0x2882E734, 0xE714F663, 0xB96E2775, 0xBD8AAFC7,
0x1DD3EC29, 0xECA4A16C, 0x5F69EC87, 0x85981E92, 0x7CFCAE21, 0xBAE9DD16,
0xE6A97804, 0x2EEE02FC, 0x61DF8A3D, 0xDD310564, 0x9697E149, 0xC2453F3B,
0xF91D8456, 0x39DA6BC8, 0xB3E5FEF5, 0x89C593A3, 0xFB5C8ABC, 0x6C0B7212,
0xE10DD3CB, 0x98D0B2A8, 0x5FD61847, 0xF0DC2357, 0x7701166A, 0x0F5C3B68};
u32 g_keyUPDATER[] = {
0xA5603CBF, 0xD7482441, 0xF65764CC, 0x1F90060B, 0x4EA73E45, 0xE551D192,
0xE7B75D8A, 0x465A506E, 0x40FB1022, 0x2C273350, 0x8096DA44, 0x9947198E,
0x278DEE77, 0x745D062E, 0xC148FA45, 0x832582AF, 0x5FDB86DA, 0xCB15C4CE,
0x2524C62F, 0x6C2EC3B1, 0x369BE39E, 0xF7EB1FC4, 0x1E51CE1A, 0xD70536F4,
0xC34D39D8, 0x7418FB13, 0xE3C84DE1, 0xB118F03C, 0xA2018D4E, 0xE6D8770D,
0x5720F390, 0x17F96341, 0x60A4A68F, 0x1327DD28, 0x05944C64, 0x0C2C4C12};
u32 g_keyMEIMG250[] = {
0xA381FEBC, 0x99B9D5C9, 0x6C560A8D, 0x30309F95, 0x792646CC, 0x82B64E5E,
0x1A3951AD, 0x0A182EC4, 0xC46131B4, 0x77C50C8A, 0x325F16C6, 0x02D1942E,
0x0AA38AC4, 0x2A940AC6, 0x67034726, 0xE52DB133, 0xD2EF2107, 0x85C81E90,
0xC8D164BA, 0xC38DCE1D, 0x948BA275, 0x0DB84603, 0xE2473637, 0xCD74FCDA,
0x588E3D66, 0x6D28E822, 0x891E548B, 0xF53CF56D, 0x0BBDDB66, 0xC4B286AA,
0x2BEBBC4B, 0xFC261FF4, 0x92B8E705, 0xDCEE6952, 0x5E0442E5, 0x8BEB7F21};
u32 g_keyMEIMG260[] = {
0x11BFD698, 0xD7F9B324, 0xDD524927, 0x16215B86, 0x504AC36D, 0x5843B217,
0xE5A0DA47, 0xBB73A1E7, 0x2915DB35, 0x375CFD3A, 0xBB70A905, 0x272BEFCA,
0x2E960791, 0xEA0799BB, 0xB85AE6C8, 0xC9CAF773, 0x250EE641, 0x06E74A9E,
0x5244895D, 0x466755A5, 0x9A84AF53, 0xE1024174, 0xEEBA031E, 0xED80B9CE,
0xBC315F72, 0x5821067F, 0xE8313058, 0xD2D0E706, 0xE6D8933E, 0xD7D17FB4,
0x505096C4, 0xFDA50B3B, 0x4635AE3D, 0xEB489C8A, 0x422D762D, 0x5A8B3231};
u32 g_keyDEMOS27X[] = {
0x1ABF102F, 0xD596D071, 0x6FC552B2, 0xD4F2531F, 0xF025CDD9, 0xAF9AAF03,
0xE0CF57CF, 0x255494C4, 0x7003675E, 0x907BC884, 0x002D4EE4, 0x0B687A0D,
0x9E3AA44F, 0xF58FDA81, 0xEC26AC8C, 0x3AC9B49D, 0x3471C037, 0xB0F3834D,
0x10DC4411, 0xA232EA31, 0xE2E5FA6B, 0x45594B03, 0xE43A1C87, 0x31DAD9D1,
0x08CD7003, 0xFA9C2FDF, 0x5A891D25, 0x9B5C1934, 0x22F366E5, 0x5F084A32,
0x695516D5, 0x2245BE9F, 0x4F6DD705, 0xC4B8B8A1, 0xBC13A600, 0x77B7FC3B};
u32 g_keyUNK1[] = {
0x33B50800, 0xF32F5FCD, 0x3C14881F, 0x6E8A2A95, 0x29FEEFD5, 0x1394EAE3,
0xBD6BD443, 0x0821C083, 0xFAB379D3, 0xE613E165, 0xF5A754D3, 0x108B2952,
0x0A4B1E15, 0x61EADEBA, 0x557565DF, 0x3B465301, 0xAE54ECC3, 0x61423309,
0x70C9FF19, 0x5B0AE5EC, 0x989DF126, 0x9D987A5F, 0x55BC750E, 0xC66EBA27,
0x2DE988E8, 0xF76600DA, 0x0382DCCB, 0x5569F5F2, 0x8E431262, 0x288FE3D3,
0x656F2187, 0x37D12E9C, 0x2F539EB4, 0xA492998E, 0xED3958F7, 0x39E96523};
u32 g_key_GAMESHARE1xx[] = {
0x721B53E8, 0xFC3E31C6, 0xF85BA2A2, 0x3CF0AC72, 0x54EEA7AB, 0x5959BFCB,
0x54B8836B, 0xBC431313, 0x989EF2CF, 0xF0CE36B2, 0x98BA4CF8, 0xE971C931,
0xA0375DC8, 0x08E52FA0, 0xAC0DD426, 0x57E4D601, 0xC56E61C7, 0xEF1AB98A,
0xD1D9F8F4, 0x5FE9A708, 0x3EF09D07, 0xFA0C1A8C, 0xA91EEA5C, 0x58F482C5,
0x2C800302, 0x7EE6F6C3, 0xFF6ABBBB, 0x2110D0D0, 0xD3297A88, 0x980012D3,
0xDC59C87B, 0x7FDC5792, 0xDB3F5DA6, 0xFC23B787, 0x22698ED3, 0xB680E812};
u32 g_key_GAMESHARE2xx[] = {
0x94A757C7, 0x9FD39833, 0xF8508371, 0x328B0B29, 0x2CBCB9DA, 0x2918B9C6,
0x944C50BA, 0xF1DCE7D0, 0x640C3966, 0xC90B3D08, 0xF4AD17BA, 0x6CA0F84B,
0xF7767C67, 0xA4D3A55A, 0x4A085C6A, 0x6BB27071, 0xFA8B38FB, 0x3FDB31B8,
0x8B7196F2, 0xDB9BED4A, 0x51625B84, 0x4C1481B4, 0xF684F508, 0x30B44770,
0x93AA8E74, 0x90C579BC, 0x246EC88D, 0x2E051202, 0xC774842E, 0xA185D997,
0x7A2B3ADD, 0xFE835B6D, 0x508F184D, 0xEB4C4F13, 0x0E1993D3, 0xBA96DFD2};
u32 g_key_INDEXDAT1xx[] = {
0x76CB00AF, 0x111CE62F, 0xB7B27E36, 0x6D8DE8F9, 0xD54BF16A, 0xD9E90373,
0x7599D982, 0x51F82B0E, 0x636103AD, 0x8E40BC35, 0x2F332C94, 0xF513AAE9,
0xD22AFEE9, 0x04343987, 0xFC5BB80C, 0x12349D89, 0x14A481BB, 0x25ED3AE8,
0x7D500E4F, 0x43D1B757, 0x7B59FDAD, 0x4CFBBF34, 0xC3D17436, 0xC1DA21DB,
0xA34D8C80, 0x962B235D, 0x3E420548, 0x09CF9FFE, 0xD4883F5C, 0xD90E9CB5,
0x00AEF4E9, 0xF0886DE9, 0x62A58A5B, 0x52A55546, 0x971941B5, 0xF5B79FAC};
typedef struct
{
u32 tag; // 4 byte value at offset 0xD0 in the PRX file
u32* key; // "step1_result" use for XOR step
u8 code;
u8 codeExtra;
} TAG_INFO;
static const TAG_INFO g_tagInfo[] =
{
{ 0x00000000, g_key0, 0x42 },
{ 0x02000000, g_key2, 0x45 },
{ 0x03000000, g_key3, 0x46 },
{ 0x4467415d, g_key44, 0x59, 0x59 },
{ 0x207bbf2f, g_key20, 0x5A, 0x5A },
{ 0x3ace4dce, g_key3A, 0x5B, 0x5B },
{ 0x07000000, g_key_INDEXDAT1xx, 0x4A },
{ 0x08000000, g_keyEBOOT1xx, 0x4B },
{ 0xC0CB167C, g_keyEBOOT2xx, 0x5D, 0x5D },
{ 0x0B000000, g_keyUPDATER, 0x4E },
{ 0x0C000000, g_keyDEMOS27X, 0x4F },
{ 0x0F000000, g_keyMEIMG250, 0x52 },
{ 0x862648D1, g_keyMEIMG260, 0x52, 0x52 },
{ 0x207BBF2F, g_keyUNK1, 0x5A, 0x5A },
{ 0x09000000, g_key_GAMESHARE1xx, 0x4C },
{ 0xBB67C59F, g_key_GAMESHARE2xx, 0x5E, 0x5E }
};
static TAG_INFO const* GetTagInfo(u32 tagFind)
{
for (u32 iTag = 0; iTag < sizeof(g_tagInfo)/sizeof(TAG_INFO); iTag++)
if (g_tagInfo[iTag].tag == tagFind)
return &g_tagInfo[iTag];
return NULL; // not found
}
static void ExtraV2Mangle(u8* buffer1, u8 codeExtra)
{
static u8 g_dataTmp[20+0xA0] __attribute__((aligned(0x40)));
u8* buffer2 = g_dataTmp; // aligned
memcpy(buffer2+20, buffer1, 0xA0);
u32* pl2 = (u32*)buffer2;
pl2[0] = 5;
pl2[1] = pl2[2] = 0;
pl2[3] = codeExtra;
pl2[4] = 0xA0;
sceUtilsBufferCopyWithRange(buffer2, 20+0xA0, buffer2, 20+0xA0, 7);
// copy result back
memcpy(buffer1, buffer2, 0xA0);
}
static int Scramble(u32 *buf, u32 size, u32 code)
{
buf[0] = 5;
buf[1] = buf[2] = 0;
buf[3] = code;
buf[4] = size;
if (sceUtilsBufferCopyWithRange((u8*)buf, size+0x14, (u8*)buf, size+0x14, 7) < 0)
{
return -1;
}
return 0;
}
static int DecryptPRX1(const u8* pbIn, u8* pbOut, int cbTotal, u32 tag)
{
int i, retsize;
u8 bD0[0x80], b80[0x50], b00[0x80], bB0[0x20];
TAG_INFO const* pti = GetTagInfo(tag);
if (pti == NULL)
{
return -1;
}
retsize = *(u32*)&pbIn[0xB0];
for (i = 0; i < 0x14; i++)
{
if (pti->key[i] != 0)
break;
}
if (i == 0x14)
{
Scramble(pti->key, 0x90, pti->code);
}
// build conversion into pbOut
if (pbIn != pbOut)
memcpy(pbOut, pbIn, cbTotal);
memcpy(bD0, pbIn+0xD0, 0x80);
memcpy(b80, pbIn+0x80, 0x50);
memcpy(b00, pbIn+0x00, 0x80);
memcpy(bB0, pbIn+0xB0, 0x20);
memset(pbOut, 0, 0x150);
memset(pbOut, 0x55, 0x40); // first $40 bytes ignored
// step3 demangle in place
u32* pl = (u32*)(pbOut+0x2C);
pl[0] = 5; // number of ulongs in the header
pl[1] = pl[2] = 0;
pl[3] = pti->code; // initial seed for PRX
pl[4] = 0x70; // size
// redo part of the SIG check (step2)
u8 buffer1[0x150];
memcpy(buffer1+0x00, bD0, 0x80);
memcpy(buffer1+0x80, b80, 0x50);
memcpy(buffer1+0xD0, b00, 0x80);
if (pti->codeExtra != 0)
ExtraV2Mangle(buffer1+0x10, pti->codeExtra);
memcpy(pbOut+0x40 /* 0x2C+20 */, buffer1+0x40, 0x40);
int ret;
int iXOR;
for (iXOR = 0; iXOR < 0x70; iXOR++)
pbOut[0x40+iXOR] = pbOut[0x40+iXOR] ^ ((u8*)pti->key)[0x14+iXOR];
ret = sceUtilsBufferCopyWithRange(pbOut+0x2C, 20+0x70, pbOut+0x2C, 20+0x70, 7);
if (ret != 0)
{
return -1;
}
for (iXOR = 0x6F; iXOR >= 0; iXOR--)
pbOut[0x40+iXOR] = pbOut[0x2C+iXOR] ^ ((u8*)pti->key)[0x20+iXOR];
memset(pbOut+0x80, 0, 0x30); // $40 bytes kept, clean up
pbOut[0xA0] = 1;
// copy unscrambled parts from header
memcpy(pbOut+0xB0, bB0, 0x20); // file size + lots of zeros
memcpy(pbOut+0xD0, b00, 0x80); // ~PSP header
// step4: do the actual decryption of code block
// point 0x40 bytes into the buffer to key info
ret = sceUtilsBufferCopyWithRange(pbOut, cbTotal, pbOut+0x40, cbTotal-0x40, 0x1);
if (ret != 0)
{
return -1;
}
// return cbTotal - 0x150; // rounded up size
return retsize;
}
////////// Decryption 2 //////////
typedef struct
{
u32 tag; // 4 byte value at offset 0xD0 in the PRX file
u8 *key; // 16 bytes keys
u8 code; // code for scramble
u8 type;
} TAG_INFO2;
static TAG_INFO2 g_tagInfo2[] =
{
{ 0x4C9494F0, keys660_k1, 0x43 },
{ 0x4C9495F0, keys660_k2, 0x43 },
{ 0x4C9490F0, keys660_k3, 0x43 },
{ 0x4C9491F0, keys660_k8, 0x43 },
{ 0x4C9493F0, keys660_k4, 0x43 },
{ 0x4C9497F0, keys660_k5, 0x43 },
{ 0x4C9492F0, keys660_k6, 0x43 },
{ 0x4C9496F0, keys660_k7, 0x43 },
{ 0x457B90F0, keys660_v1, 0x5B },
{ 0x457B91F0, keys660_v7, 0x5B },
{ 0x457B92F0, keys660_v6, 0x5B },
{ 0x457B93F0, keys660_v3, 0x5B },
{ 0x380290F0, keys660_v2, 0x5A },
{ 0x380291F0, keys660_v8, 0x5A },
{ 0x380292F0, keys660_v4, 0x5A },
{ 0x380293F0, keys660_v5, 0x5A },
{ 0x4C948CF0, keys639_k3, 0x43 },
{ 0x4C948DF0, keys638_k4, 0x43 },
{ 0x4C948BF0, keys636_k2, 0x43 },
{ 0x4C948AF0, keys636_k1, 0x43 },
{ 0x4C9487F0, keys630_k8, 0x43 },
{ 0x457B83F0, keys630_k7, 0x5B },
{ 0x4C9486F0, keys630_k6, 0x43 },
{ 0x457B82F0, keys630_k5, 0x5B },
{ 0x457B81F0, keys630_k4, 0x5B },
{ 0x4C9485F0, keys630_k3, 0x43 },
{ 0x457B80F0, keys630_k2, 0x5B },
{ 0x4C9484F0, keys630_k1, 0x43 },
{ 0x457B28F0, keys620_e, 0x5B },
{ 0x457B0CF0, keys620_a, 0x5B },
{ 0x380228F0, keys620_5v, 0x5A },
{ 0x4C942AF0, keys620_5k, 0x43 },
{ 0x4C9428F0, keys620_5, 0x43 },
{ 0x4C941DF0, keys620_1, 0x43 },
{ 0x4C941CF0, keys620_0, 0x43 },
{ 0x4C9422F0, keys600_2, 0x43 },
{ 0x4C941EF0, keys600_1, 0x43 },
{ 0x4C9429F0, keys570_5k, 0x43 },
{ 0x457B0BF0, keys505_a, 0x5B },
{ 0x4C9419F0, keys505_1, 0x43 },
{ 0x4C9418F0, keys505_0, 0x43 },
{ 0x457B1EF0, keys500_c, 0x5B },
{ 0x4C941FF0, keys500_2, 0x43 },
{ 0x4C9417F0, keys500_1, 0x43 },
{ 0x4C9416F0, keys500_0, 0x43 },
{ 0x4C9414F0, keys390_0, 0x43 },
{ 0x4C9415F0, keys390_1, 0x43 },
{ 0x4C9412F0, keys370_0, 0x43 },
{ 0x4C9413F0, keys370_1, 0x43 },
{ 0x457B10F0, keys370_2, 0x5B },
{ 0x4C940DF0, keys360_0, 0x43 },
{ 0x4C9410F0, keys360_1, 0x43 },
{ 0x4C940BF0, keys330_0, 0x43 },
{ 0x457B0AF0, keys330_1, 0x5B },
{ 0x38020AF0, keys330_2, 0x5A },
{ 0x4C940AF0, keys330_3, 0x43 },
{ 0x4C940CF0, keys330_4, 0x43 },
{ 0xcfef09f0, keys310_0, 0x62 },
{ 0x457b08f0, keys310_1, 0x5B },
{ 0x380208F0, keys310_2, 0x5A },
{ 0xcfef08f0, keys310_3, 0x62 },
{ 0xCFEF07F0, keys303_0, 0x62 },
{ 0xCFEF06F0, keys300_0, 0x62 },
{ 0x457B06F0, keys300_1, 0x5B },
{ 0x380206F0, keys300_2, 0x5A },
{ 0xCFEF05F0, keys280_0, 0x62 },
{ 0x457B05F0, keys280_1, 0x5B },
{ 0x380205F0, keys280_2, 0x5A },
{ 0x16D59E03, keys260_0, 0x62 },
{ 0x76202403, keys260_1, 0x5B },
{ 0x0F037303, keys260_2, 0x5A },
{ 0x4C940FF0, key_2DA8, 0x43 },
{ 0x4467415D, key_22E0, 0x59 },
{ 0x00000000, key_21C0, 0x42 },
{ 0x01000000, key_2250, 0x43 },
{ 0x2E5E10F0, key_2E5E10F0, 0x48 },
{ 0x2E5E12F0, key_2E5E12F0, 0x48 },
{ 0x2E5E13F0, key_2E5E13F0, 0x48 },
{ 0x2FD30BF0, key_2FD30BF0, 0x47 },
{ 0x2FD311F0, key_2FD311F0, 0x47 },
{ 0x2FD312F0, key_2FD312F0, 0x47 },
{ 0xD91605F0, key_D91605F0, 0x5D },
{ 0xD91606F0, key_D91606F0, 0x5D },
{ 0xD91608F0, key_D91608F0, 0x5D },
{ 0xD91609F0, key_D91609F0, 0x5D },
{ 0xD9160AF0, key_D9160AF0, 0x5D },
{ 0xD9160BF0, key_D9160BF0, 0x5D },
{ 0xD91611F0, key_D91611F0, 0x5D },
{ 0xD91612F0, key_D91612F0, 0x5D },
{ 0xD91613F0, key_D91613F0, 0x5D },
{ 0xD91614F0, key_D91614F0, 0x5D },
{ 0xD91615F0, key_D91615F0, 0x5D },
{ 0xD91616F0, key_D91616F0, 0x5D },
{ 0xD91617F0, key_D91617F0, 0x5D },
{ 0xD91618F0, key_D91618F0, 0x5D },
{ 0xD91619F0, key_D91619F0, 0x5D },
{ 0xD9161AF0, key_D9161AF0, 0x5D },
{ 0xD91620F0, key_D91620F0, 0x5D },
{ 0xD91621F0, key_D91621F0, 0x5D },
{ 0xD91622F0, key_D91622F0, 0x5D },
{ 0xD91623F0, key_D91623F0, 0x5D },
{ 0xD91624F0, key_D91624F0, 0x5D },
{ 0xD91628F0, key_D91628F0, 0x5D },
{ 0xD91680F0, key_D91680F0, 0x5D },
{ 0xD91681F0, key_D91681F0, 0x5D },
{ 0xD82310F0, keys02G_E, 0x51 },
{ 0xD8231EF0, keys03G_E, 0x51 },
{ 0xD82328F0, keys05G_E, 0x51 },
{ 0x279D08F0, oneseg_310, 0x61 },
{ 0x279D06F0, oneseg_300, 0x61 },
{ 0x279D05F0, oneseg_280, 0x61 },
{ 0xD66DF703, oneseg_260_271, 0x61 },
{ 0x279D10F0, oneseg_slim, 0x61 },
{ 0x3C2A08F0, ms_app_main, 0x67 },
{ 0xADF305F0, demokeys_280, 0x60 },
{ 0xADF306F0, demokeys_3XX_1, 0x60 },
{ 0xADF308F0, demokeys_3XX_2, 0x60 },
{ 0x8004FD03, ebootbin_271_new, 0x5D },
{ 0xD91605F0, ebootbin_280_new, 0x5D },
{ 0xD91606F0, ebootbin_300_new, 0x5D },
{ 0xD91608F0, ebootbin_310_new, 0x5D },
{ 0x0A35EA03, gameshare_260_271, 0x5E },
{ 0x7B0505F0, gameshare_280, 0x5E },
{ 0x7B0506F0, gameshare_300, 0x5E },
{ 0x7B0508F0, gameshare_310, 0x5E },
{ 0x380210F0, key_380210F0, 0x5A },
{ 0x380280F0, key_380280F0, 0x5A },
{ 0x380283F0, key_380283F0, 0x5A },
{ 0x407810F0, key_407810F0, 0x6A },
{ 0xE92410F0, drmkeys_6XX_1, 0x40 },
{ 0x692810F0, drmkeys_6XX_2, 0x40 }
};
static TAG_INFO2 *GetTagInfo2(u32 tagFind)
{
for (u32 iTag = 0; iTag < sizeof(g_tagInfo2) / sizeof(TAG_INFO2); iTag++)
{
if (g_tagInfo2[iTag].tag == tagFind)
{
return &g_tagInfo2[iTag];
}
}
return NULL; // not found
}
static int DecryptPRX2(const u8 *inbuf, u8 *outbuf, u32 size, u32 tag)
{
TAG_INFO2 * pti = GetTagInfo2(tag);
if (!pti)
{
return -1;
}
int retsize = *(int *)&inbuf[0xB0];
u8 tmp1[0x150], tmp2[0x90+0x14], tmp3[0x60+0x14], tmp4[0x20];
memset(tmp1, 0, 0x150);
memset(tmp2, 0, 0x90+0x14);
memset(tmp3, 0, 0x60+0x14);
memset(tmp4, 0, 0x20);
if (inbuf != outbuf)
memcpy(outbuf, inbuf, size);
if (size < 0x160)
{
return -2;
}
if (((size_t)(void*)outbuf & 0x3F))
{
return -3;
}
if ((size - 0x150) < retsize)
{
return -4;
}
memcpy(tmp1, outbuf, 0x150);
int i, j;
u8 *p = tmp2+0x14;
for (i = 0; i < 9; i++)
{
for (j = 0; j < 0x10; j++)
{
p[(i << 4) + j] = pti->key[j];
}
p[(i << 4)] = i;
}
if (Scramble((u32 *)tmp2, 0x90, pti->code) < 0)
{
return -5;
}
memcpy(outbuf, tmp1+0xD0, 0x5C);
memcpy(outbuf+0x5C, tmp1+0x140, 0x10);
memcpy(outbuf+0x6C, tmp1+0x12C, 0x14);
memcpy(outbuf+0x80, tmp1+0x080, 0x30);
memcpy(outbuf+0xB0, tmp1+0x0C0, 0x10);
memcpy(outbuf+0xC0, tmp1+0x0B0, 0x10);
memcpy(outbuf+0xD0, tmp1+0x000, 0x80);
memcpy(tmp3+0x14, outbuf+0x5C, 0x60);
if (Scramble((u32 *)tmp3, 0x60, pti->code) < 0)
{
return -6;
}
memcpy(outbuf+0x5C, tmp3, 0x60);
memcpy(tmp3, outbuf+0x6C, 0x14);
memcpy(outbuf+0x70, outbuf+0x5C, 0x10);
if(pti->type == 3)
{
memcpy(tmp4, outbuf+0x3C, 0x20);
memcpy(outbuf+0x50, tmp4, 0x20);
memset(outbuf+0x18, 0, 0x38);
}else
memset(outbuf+0x18, 0, 0x58);
memcpy(outbuf+0x04, outbuf, 0x04);
*((u32 *)outbuf) = 0x014C;
memcpy(outbuf+0x08, tmp2, 0x10);
/* sha-1 */
if (sceUtilsBufferCopyWithRange(outbuf, 3000000, outbuf, 3000000, 0x0B) != 0)
{
return -7;
}
if (memcmp(outbuf, tmp3, 0x14) != 0)
{
return -8;
}
int iXOR;
for (iXOR = 0; iXOR < 0x40; iXOR++)
{
tmp3[iXOR+0x14] = outbuf[iXOR+0x80] ^ tmp2[iXOR+0x10];
}
if (Scramble((u32 *)tmp3, 0x40, pti->code) != 0)
{
return -9;
}
for (iXOR = 0x3F; iXOR >= 0; iXOR--)
{
outbuf[iXOR+0x40] = tmp3[iXOR] ^ tmp2[iXOR+0x50]; // uns 8
}
if (pti->type == 3)
{
memcpy(outbuf+0x80, tmp4, 0x20);
memset(outbuf+0xA0, 0, 0x10);
*(u32*)&outbuf[0xA4] = 1;
*(u32*)&outbuf[0xA0] = 1;
}
else
{
memset(outbuf+0x80, 0, 0x30);
*(u32*)&outbuf[0xA0] = 1;
}
memcpy(outbuf+0xB0, outbuf+0xC0, 0x10);
memset(outbuf+0xC0, 0, 0x10);
memcpy(outbuf+0xD0, outbuf+0xD0, 0x80);
// The real decryption
if (sceUtilsBufferCopyWithRange(outbuf, size, outbuf+0x40, size-0x40, 0x1) != 0)
{
return -1;
}
if (retsize < 0x150)
{
// Fill with 0
memset(outbuf+retsize, 0, 0x150-retsize);
}
return retsize;
}
int pspDecryptPRX(const u8 *inbuf, u8 *outbuf, u32 size)
{
kirk_init();
int retsize = DecryptPRX1(inbuf, outbuf, size, *(u32 *)&inbuf[0xD0]);
if (retsize <= 0)
{
retsize = DecryptPRX2(inbuf, outbuf, size, *(u32 *)&inbuf[0xD0]);
}
return retsize;
}

56
Core/ELF/PrxDecrypter.h Normal file
View File

@ -0,0 +1,56 @@
// Copyright (c) 2012- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#pragma once
#include "../../Globals.h"
typedef struct
{
u32 signature; // 0
u16 attribute; // 4 modinfo
u16 comp_attribute; // 6
u8 module_ver_lo; // 8
u8 module_ver_hi; // 9
char modname[28]; // 0A
u8 version; // 26
u8 nsegments; // 27
int elf_size; // 28
int psp_size; // 2C
u32 entry; // 30
u32 modinfo_offset; // 34
int bss_size; // 38
u16 seg_align[4]; // 3C
u32 seg_address[4]; // 44
int seg_size[4]; // 54
u32 reserved[5]; // 64
u32 devkitversion; // 78
u32 decrypt_mode; // 7C
u8 key_data0[0x30]; // 80
int comp_size; // B0
int _80; // B4
int reserved2[2]; // B8
u8 key_data1[0x10]; // C0
u32 tag; // D0
u8 scheck[0x58]; // D4
u32 key_data2; // 12C
u32 oe_tag; // 130
u8 key_data3[0x1C]; // 134
} __attribute__((packed)) PSP_Header;
int pspDecryptPRX(const u8 *inbuf, u8 *outbuf, u32 size);

View File

@ -23,6 +23,7 @@
#include "../MIPS/MIPS.h"
#include "../MIPS/MIPSAnalyst.h"
#include "../ELF/ElfReader.h"
#include "../ELF/PrxDecrypter.h"
#include "../Debugger/SymbolMap.h"
#include "../FileSystems/FileSystem.h"
#include "../FileSystems/MetaFileSystem.h"
@ -139,27 +140,24 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro
Module *module = new Module;
kernelObjects.Create(module);
u32 magic = *((u32*)ptr);
u8 *newptr = 0;
if (magic == 0x5053507e) { // "~PSP"
ERROR_LOG(HLE, "File encrypted - not yet supported");
*error_string = "Executable encrypted - not yet supported";
return 0;
if (*(u32*)ptr == 0x5053507e) { // "~PSP"
// Decrypt module! YAY!
INFO_LOG(HLE, "Decrypting ~PSP file");
PSP_Header *head = (PSP_Header*)ptr;
const u8 *in = ptr;
newptr = new u8[head->elf_size + 0x40];
ptr = (u8*)(((size_t)newptr & ~0x3C) + 0x40);
pspDecryptPRX(in, (u8*)ptr, head->psp_size);
}
if (magic == 0x00000000) {
// BOOT.BIN is empty, we have to look for EBOOT.BIN which is encrypted.
ERROR_LOG(HLE, "File encrypted - not yet supported (2)");
*error_string = "Executable encrypted - not yet supported";
return 0;
}
if (*(u32*)ptr != 0x464c457f)
{
char c[4];
memcpy(c, ptr, 4);
ERROR_LOG(HLE, "Wrong magic number %c%c%c%c %08x", c[0],c[1],c[2],c[3],*(u32*)ptr);
*error_string = "File corrupt or encrypted?";
ERROR_LOG(HLE, "Wrong magic number %08x",*(u32*)ptr);
*error_string = "File corrupt";
delete newptr;
kernelObjects.Destroy<Module>(module->GetUID());
return 0;
}
// Open ELF reader
@ -168,6 +166,8 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro
if (!reader.LoadInto(loadAddress))
{
ERROR_LOG(HLE, "LoadInto failed");
delete newptr;
kernelObjects.Destroy<Module>(module->GetUID());
return 0;
}
@ -341,6 +341,7 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro
module->entry_addr = reader.GetEntryPoint();
delete newptr;
return module;
}
@ -392,7 +393,6 @@ bool __KernelLoadPBP(const char *filename, std::string *error_string)
return true;
}
Module *__KernelLoadModule(u8 *fileptr, SceKernelLMOption *options, std::string *error_string)
{
Module *module = 0;

View File

@ -20,7 +20,6 @@
#include "sceKernel.h"
#include "HLE.h"
bool __KernelLoadPBP(const char *filename, std::string *error_string);
u32 __KernelGetModuleGP(SceUID module);
bool __KernelLoadExec(const char *filename, SceKernelLoadExecParam *param, std::string *error_string);

View File

@ -64,8 +64,23 @@ bool Load_PSP_ISO(const char *filename, std::string *error_string)
pspFileSystem.Mount("UMD1:", umd2);
pspFileSystem.Mount("DISC0:", umd2);
std::string bootpath("disc0:/PSP_GAME/SYSDIR/BOOT.BIN");
//std::string bootpath("/PSP_GAME/USRDIR/locoroco/locoroco.prx");
std::string bootpath("disc0:/PSP_GAME/SYSDIR/EBOOT.BIN");
bool hasEncrypted = false;
u32 fd;
if ((fd = pspFileSystem.OpenFile(bootpath, FILEACCESS_READ)) != 0)
{
u8 head[4];
pspFileSystem.ReadFile(fd, head, 4);
if (memcmp(head, "~PSP", 4) == 0)
{
hasEncrypted = true;
}
}
if (!hasEncrypted)
{
// try unencrypted BOOT.BIN
bootpath = "disc0:/PSP_GAME/SYSDIR/BOOT.BIN";
}
INFO_LOG(LOADER,"Loading %s...", bootpath.c_str());
return __KernelLoadExec(bootpath.c_str(), 0, error_string);

View File

@ -68,11 +68,12 @@ add_subdirectory(../native/ext/vjson vjson)
add_subdirectory(../native/ext/stb_vorbis stb_vorbis)
add_subdirectory(../native/ext/stb_image stb_image)
add_subdirectory(../native/ext/sha1 sha1)
add_subdirectory(../ext/libkirk kirk)
add_subdirectory(../Common Common)
add_subdirectory(../GPU GPU)
add_subdirectory(../Core Core)
set(LIBS ${LIBS} ${SDL_LIBRARY} ${OPENGL_LIBRARIES} file lin ${PNG_LIBRARY} z gfx gfx_es2 etcdec image stb_image mixer net ui profiler timeutil file zip base lin vjson stb_vorbis sha1 jsonwriter common core gpu)
set(LIBS ${LIBS} ${SDL_LIBRARY} ${OPENGL_LIBRARIES} file lin ${PNG_LIBRARY} z gfx gfx_es2 etcdec image stb_image mixer net ui profiler timeutil file zip base lin vjson stb_vorbis sha1 jsonwriter common core gpu kirk)
# TODO: Blackberry specific libs (eg. TCO)
if(BLACKBERRY)

View File

@ -10,7 +10,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PPSSPPWindows", "PPSSPP.vcx
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "..\Common\Common.vcxproj", "{3FCDBAE2-5103-4350-9A8E-848CE9C73195}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\zlib\zlib.vcxproj", "{F761046E-6C38-4428-A5F1-38391A37BB34}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\ext\zlib\zlib.vcxproj", "{F761046E-6C38-4428-A5F1-38391A37BB34}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GPU", "..\GPU\GPU.vcxproj", "{457F45D2-556F-47BC-A31D-AFF0D15BEAED}"
ProjectSection(ProjectDependencies) = postProject

View File

@ -136,7 +136,7 @@
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../zlib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
@ -164,7 +164,7 @@
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../zlib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
@ -195,7 +195,7 @@
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../zlib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
</ClCompile>
@ -230,7 +230,7 @@
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../zlib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
</ClCompile>
<Link>
@ -257,11 +257,11 @@
</AssemblerOutput>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../zlib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
</ClCompile>
<Link>
<AdditionalDependencies>Ws2_32.lib;comctl32.lib;../zlib/zdll.lib;imgdecoder.lib;opengl32.lib;dsound.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>Ws2_32.lib;comctl32.lib;../ext/zlib/zdll.lib;imgdecoder.lib;opengl32.lib;dsound.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalLibraryDirectories>../elfio/release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -283,7 +283,7 @@
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../zlib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../common;..;../native;../native/ext/glew;../ext/zlib</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>imgdecoder.lib;opengl32.lib;dsound.lib;glu32.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -443,7 +443,7 @@
<ProjectReference Include="..\native\native.vcxproj">
<Project>{e8b58922-9827-493d-81e0-4b6e6bd77171}</Project>
</ProjectReference>
<ProjectReference Include="..\zlib\zlib.vcxproj">
<ProjectReference Include="..\ext\zlib\zlib.vcxproj">
<Project>{f761046e-6c38-4428-a5f1-38391a37bb34}</Project>
</ProjectReference>
</ItemGroup>
@ -455,4 +455,4 @@
<UserProperties RESOURCE_FILE="DaSh.rc" />
</VisualStudio>
</ProjectExtensions>
</Project>
</Project>

1464
ext/libkirk/AES.c Normal file

File diff suppressed because it is too large Load Diff

52
ext/libkirk/AES.h Normal file
View File

@ -0,0 +1,52 @@
#ifndef __RIJNDAEL_H
#define __RIJNDAEL_H
#include "kirk_engine.h"
#define AES_KEY_LEN_128 (128)
#define AES_KEY_LEN_192 (192)
#define AES_KEY_LEN_256 (256)
#define AES_BUFFER_SIZE (16)
#define AES_MAXKEYBITS (256)
#define AES_MAXKEYBYTES (AES_MAXKEYBITS/8)
/* for 256-bit keys, fewer for less */
#define AES_MAXROUNDS 14
#define pwuAESContextBuffer rijndael_ctx
/* The structure for key information */
typedef struct
{
int enc_only; /* context contains only encrypt schedule */
int Nr; /* key-length-dependent number of rounds */
u32 ek[4*(AES_MAXROUNDS + 1)]; /* encrypt key schedule */
u32 dk[4*(AES_MAXROUNDS + 1)]; /* decrypt key schedule */
} rijndael_ctx;
typedef struct
{
int enc_only; /* context contains only encrypt schedule */
int Nr; /* key-length-dependent number of rounds */
u32 ek[4*(AES_MAXROUNDS + 1)]; /* encrypt key schedule */
u32 dk[4*(AES_MAXROUNDS + 1)]; /* decrypt key schedule */
} AES_ctx;
int rijndael_set_key(rijndael_ctx *, const u8 *, int);
int rijndael_set_key_enc_only(rijndael_ctx *, const u8 *, int);
void rijndael_decrypt(rijndael_ctx *, const u8 *, u8 *);
void rijndael_encrypt(rijndael_ctx *, const u8 *, u8 *);
int AES_set_key(AES_ctx *ctx, const u8 *key, int bits);
void AES_encrypt(AES_ctx *ctx, const u8 *src, u8 *dst);
void AES_decrypt(AES_ctx *ctx, const u8 *src, u8 *dst);
void AES_cbc_encrypt(AES_ctx *ctx, u8 *src, u8 *dst, int size);
void AES_cbc_decrypt(AES_ctx *ctx, u8 *src, u8 *dst, int size);
void AES_CMAC(AES_ctx *ctx, unsigned char *input, int length, unsigned char *mac);
int rijndaelKeySetupEnc(unsigned int [], const unsigned char [], int);
int rijndaelKeySetupDec(unsigned int [], const unsigned char [], int);
void rijndaelEncrypt(const unsigned int [], int, const unsigned char [],
unsigned char []);
#endif /* __RIJNDAEL_H */

View File

@ -0,0 +1,16 @@
set(SRCS
AES.c
bn.c
ec.c
kirk_engine.c
SHA1.c
)
set(SRCS ${SRCS})
add_library(kirk STATIC ${SRCS})
if(UNIX)
add_definitions(-fPIC)
endif(UNIX)

393
ext/libkirk/SHA1.c Normal file
View File

@ -0,0 +1,393 @@
/* sha1.c : Implementation of the Secure Hash Algorithm */
/* SHA: NIST's Secure Hash Algorithm */
/* This version written November 2000 by David Ireland of
DI Management Services Pty Limited <code@di-mgt.com.au>
Adapted from code in the Python Cryptography Toolkit,
version 1.0.0 by A.M. Kuchling 1995.
*/
/* AM Kuchling's posting:-
Based on SHA code originally posted to sci.crypt by Peter Gutmann
in message <30ajo5$oe8@ccu2.auckland.ac.nz>.
Modified to test for endianness on creation of SHA objects by AMK.
Also, the original specification of SHA was found to have a weakness
by NSA/NIST. This code implements the fixed version of SHA.
*/
/* Here's the first paragraph of Peter Gutmann's posting:
The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
what's changed in the new version. The fix is a simple change which involves
adding a single rotate in the initial expansion function. It is unknown
whether this is an optimal solution to the problem which was discovered in the
SHA or whether it's simply a bandaid which fixes the problem with a minimum of
effort (for example the reengineering of a great many Capstone chips).
*/
/* h files included here to make this just one file ... */
/* global.h */
/* sha.c */
#include "SHA1.h"
#include <stdio.h>
#include <string.h>
static void SHAtoByte(BYTE *output, UINT4 *input, unsigned int len);
/* The SHS block size and message digest sizes, in bytes */
#define SHS_DATASIZE 64
#define SHS_DIGESTSIZE 20
/* The SHS f()-functions. The f1 and f3 functions can be optimized to
save one boolean operation each - thanks to Rich Schroeppel,
rcs@cs.arizona.edu for discovering this */
/*#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) // Rounds 0-19 */
#define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */
#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
/*#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) // Rounds 40-59 */
#define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */
#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
/* The SHS Mysterious Constants */
#define K1 0x5A827999L /* Rounds 0-19 */
#define K2 0x6ED9EBA1L /* Rounds 20-39 */
#define K3 0x8F1BBCDCL /* Rounds 40-59 */
#define K4 0xCA62C1D6L /* Rounds 60-79 */
/* SHS initial values */
#define h0init 0x67452301L
#define h1init 0xEFCDAB89L
#define h2init 0x98BADCFEL
#define h3init 0x10325476L
#define h4init 0xC3D2E1F0L
/* Note that it may be necessary to add parentheses to these macros if they
are to be called with expressions as arguments */
/* 32-bit rotate left - kludged with shifts */
#define ROTL(n,X) ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
/* The initial expanding function. The hash function is defined over an
80-UINT2 expanded input array W, where the first 16 are copies of the input
data, and the remaining 64 are defined by
W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
This implementation generates these values on the fly in a circular
buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
optimization.
The updated SHS changes the expanding function by adding a rotate of 1
bit. Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
for this information */
#define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
/* The prototype SHS sub-round. The fundamental sub-round is:
a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
b' = a;
c' = ROTL( 30, b );
d' = c;
e' = d;
but this is implemented by unrolling the loop 5 times and renaming the
variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
This code is then replicated 20 times for each of the 4 functions, using
the next 20 values from the W[] array each time */
#define subRound(a, b, c, d, e, f, k, data) \
( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
/* Initialize the SHS values */
void SHAInit(SHA_CTX *shsInfo)
{
endianTest(&shsInfo->Endianness);
/* Set the h-vars to their initial values */
shsInfo->digest[ 0 ] = h0init;
shsInfo->digest[ 1 ] = h1init;
shsInfo->digest[ 2 ] = h2init;
shsInfo->digest[ 3 ] = h3init;
shsInfo->digest[ 4 ] = h4init;
/* Initialise bit count */
shsInfo->countLo = shsInfo->countHi = 0;
}
/* Perform the SHS transformation. Note that this code, like MD5, seems to
break some optimizing compilers due to the complexity of the expressions
and the size of the basic block. It may be necessary to split it into
sections, e.g. based on the four subrounds
Note that this corrupts the shsInfo->data area */
static void SHSTransform( digest, data )
UINT4 *digest, *data ;
{
UINT4 A, B, C, D, E; /* Local vars */
UINT4 eData[ 16 ]; /* Expanded data */
/* Set up first buffer and local data buffer */
A = digest[ 0 ];
B = digest[ 1 ];
C = digest[ 2 ];
D = digest[ 3 ];
E = digest[ 4 ];
memcpy( (POINTER)eData, (POINTER)data, SHS_DATASIZE );
/* Heavy mangling, in 4 sub-rounds of 20 interations each. */
subRound( A, B, C, D, E, f1, K1, eData[ 0 ] );
subRound( E, A, B, C, D, f1, K1, eData[ 1 ] );
subRound( D, E, A, B, C, f1, K1, eData[ 2 ] );
subRound( C, D, E, A, B, f1, K1, eData[ 3 ] );
subRound( B, C, D, E, A, f1, K1, eData[ 4 ] );
subRound( A, B, C, D, E, f1, K1, eData[ 5 ] );
subRound( E, A, B, C, D, f1, K1, eData[ 6 ] );
subRound( D, E, A, B, C, f1, K1, eData[ 7 ] );
subRound( C, D, E, A, B, f1, K1, eData[ 8 ] );
subRound( B, C, D, E, A, f1, K1, eData[ 9 ] );
subRound( A, B, C, D, E, f1, K1, eData[ 10 ] );
subRound( E, A, B, C, D, f1, K1, eData[ 11 ] );
subRound( D, E, A, B, C, f1, K1, eData[ 12 ] );
subRound( C, D, E, A, B, f1, K1, eData[ 13 ] );
subRound( B, C, D, E, A, f1, K1, eData[ 14 ] );
subRound( A, B, C, D, E, f1, K1, eData[ 15 ] );
subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) );
subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) );
subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) );
subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) );
subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) );
subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) );
subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) );
subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) );
subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) );
subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) );
subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) );
subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) );
subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) );
subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) );
subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) );
subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) );
subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) );
subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) );
subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) );
subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) );
subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) );
subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) );
subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) );
subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) );
subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) );
subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) );
subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) );
subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) );
subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) );
subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) );
subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) );
subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) );
subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) );
subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) );
subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) );
subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) );
subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) );
subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) );
subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) );
subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) );
subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) );
subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) );
subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) );
subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) );
subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) );
subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) );
subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) );
subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) );
subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) );
subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) );
subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) );
subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) );
subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) );
subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) );
subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) );
subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) );
subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) );
subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) );
subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) );
subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) );
subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) );
subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) );
subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) );
subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) );
/* Build message digest */
digest[ 0 ] += A;
digest[ 1 ] += B;
digest[ 2 ] += C;
digest[ 3 ] += D;
digest[ 4 ] += E;
}
/* When run on a little-endian CPU we need to perform byte reversal on an
array of long words. */
static void longReverse(UINT4 *buffer, int byteCount, int Endianness )
{
UINT4 value;
if (Endianness==TRUE) return;
byteCount /= sizeof( UINT4 );
while( byteCount-- )
{
value = *buffer;
value = ( ( value & 0xFF00FF00L ) >> 8 ) | \
( ( value & 0x00FF00FFL ) << 8 );
*buffer++ = ( value << 16 ) | ( value >> 16 );
}
}
/* Update SHS for a block of data */
void SHAUpdate(SHA_CTX *shsInfo, BYTE *buffer, int count)
{
UINT4 tmp;
int dataCount;
/* Update bitcount */
tmp = shsInfo->countLo;
if ( ( shsInfo->countLo = tmp + ( ( UINT4 ) count << 3 ) ) < tmp )
shsInfo->countHi++; /* Carry from low to high */
shsInfo->countHi += count >> 29;
/* Get count of bytes already in data */
dataCount = ( int ) ( tmp >> 3 ) & 0x3F;
/* Handle any leading odd-sized chunks */
if( dataCount )
{
BYTE *p = ( BYTE * ) shsInfo->data + dataCount;
dataCount = SHS_DATASIZE - dataCount;
if( count < dataCount )
{
memcpy( p, buffer, count );
return;
}
memcpy( p, buffer, dataCount );
longReverse( shsInfo->data, SHS_DATASIZE, shsInfo->Endianness);
SHSTransform( shsInfo->digest, shsInfo->data );
buffer += dataCount;
count -= dataCount;
}
/* Process data in SHS_DATASIZE chunks */
while( count >= SHS_DATASIZE )
{
memcpy( (POINTER)shsInfo->data, (POINTER)buffer, SHS_DATASIZE );
longReverse( shsInfo->data, SHS_DATASIZE, shsInfo->Endianness );
SHSTransform( shsInfo->digest, shsInfo->data );
buffer += SHS_DATASIZE;
count -= SHS_DATASIZE;
}
/* Handle any remaining bytes of data. */
memcpy( (POINTER)shsInfo->data, (POINTER)buffer, count );
}
/* Final wrapup - pad to SHS_DATASIZE-byte boundary with the bit pattern
1 0* (64-bit count of bits processed, MSB-first) */
void SHAFinal(BYTE *output, SHA_CTX *shsInfo)
{
int count;
BYTE *dataPtr;
/* Compute number of bytes mod 64 */
count = ( int ) shsInfo->countLo;
count = ( count >> 3 ) & 0x3F;
/* Set the first char of padding to 0x80. This is safe since there is
always at least one byte free */
dataPtr = ( BYTE * ) shsInfo->data + count;
*dataPtr++ = 0x80;
/* Bytes of padding needed to make 64 bytes */
count = SHS_DATASIZE - 1 - count;
/* Pad out to 56 mod 64 */
if( count < 8 )
{
/* Two lots of padding: Pad the first block to 64 bytes */
memset( dataPtr, 0, count );
longReverse( shsInfo->data, SHS_DATASIZE, shsInfo->Endianness );
SHSTransform( shsInfo->digest, shsInfo->data );
/* Now fill the next block with 56 bytes */
memset( (POINTER)shsInfo->data, 0, SHS_DATASIZE - 8 );
}
else
/* Pad block to 56 bytes */
memset( dataPtr, 0, count - 8 );
/* Append length in bits and transform */
shsInfo->data[ 14 ] = shsInfo->countHi;
shsInfo->data[ 15 ] = shsInfo->countLo;
longReverse( shsInfo->data, SHS_DATASIZE - 8, shsInfo->Endianness );
SHSTransform( shsInfo->digest, shsInfo->data );
/* Output to an array of bytes */
SHAtoByte(output, shsInfo->digest, SHS_DIGESTSIZE);
/* Zeroise sensitive stuff */
memset((POINTER)shsInfo, 0, sizeof(shsInfo));
}
static void SHAtoByte(BYTE *output, UINT4 *input, unsigned int len)
{ /* Output SHA digest in byte array */
unsigned int i, j;
for(i = 0, j = 0; j < len; i++, j += 4)
{
output[j+3] = (BYTE)( input[i] & 0xff);
output[j+2] = (BYTE)((input[i] >> 8 ) & 0xff);
output[j+1] = (BYTE)((input[i] >> 16) & 0xff);
output[j ] = (BYTE)((input[i] >> 24) & 0xff);
}
}
/* endian.c */
void endianTest(int *endian_ness)
{
if((*(unsigned short *) ("#S") >> 8) == '#')
{
/* printf("Big endian = no change\n"); */
*endian_ness = !(0);
}
else
{
/* printf("Little endian = swap\n"); */
*endian_ness = 0;
}
}

52
ext/libkirk/SHA1.h Normal file
View File

@ -0,0 +1,52 @@
#ifndef _GLOBAL_H_
#define _GLOBAL_H_ 1
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* UINT4 defines a four byte word */
typedef unsigned int UINT4;
/* BYTE defines a unsigned character */
typedef unsigned char BYTE;
#ifndef TRUE
#define FALSE 0
#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
{
UINT4 digest[ 5 ]; /* Message digest */
UINT4 countLo, countHi; /* 64-bit bit count */
UINT4 data[ 16 ]; /* SHS data buffer */
int Endianness;
} SHA_CTX;
/* Message digest functions */
void SHAInit(SHA_CTX *);
void SHAUpdate(SHA_CTX *, 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_ */

202
ext/libkirk/bn.c Normal file
View File

@ -0,0 +1,202 @@
// Copyright 2007,2008,2010 Segher Boessenkool <segher@kernel.crashing.org>
// Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
// Updated and simplified for use by Kirk Engine - July 2011
#include <string.h>
#include <stdio.h>
// Include definitions from kirk header
#include "kirk_engine.h"
void bn_print(char *name, u8 *a, u32 n)
{
u32 i;
printf("%s = ", name);
for (i = 0; i < n; i++)
printf("%02x", a[i]);
printf("\n");
}
static void bn_zero(u8 *d, u32 n)
{
memset(d, 0, n);
}
void bn_copy(u8 *d, u8 *a, u32 n)
{
memcpy(d, a, n);
}
int bn_compare(u8 *a, u8 *b, u32 n)
{
u32 i;
for (i = 0; i < n; i++) {
if (a[i] < b[i])
return -1;
if (a[i] > b[i])
return 1;
}
return 0;
}
static u8 bn_add_1(u8 *d, u8 *a, u8 *b, u32 n)
{
u32 i;
u32 dig;
u8 c;
c = 0;
for (i = n - 1; i < n; i--) {
dig = a[i] + b[i] + c;
c = dig >> 8;
d[i] = dig;
}
return c;
}
static u8 bn_sub_1(u8 *d, u8 *a, u8 *b, u32 n)
{
u32 i;
u32 dig;
u8 c;
c = 1;
for (i = n - 1; i < n; i--) {
dig = a[i] + 255 - b[i] + c;
c = dig >> 8;
d[i] = dig;
}
return 1 - c;
}
void bn_reduce(u8 *d, u8 *N, u32 n)
{
if (bn_compare(d, N, n) >= 0)
bn_sub_1(d, d, N, n);
}
void bn_add(u8 *d, u8 *a, u8 *b, u8 *N, u32 n)
{
if (bn_add_1(d, a, b, n))
bn_sub_1(d, d, N, n);
bn_reduce(d, N, n);
}
void bn_sub(u8 *d, u8 *a, u8 *b, u8 *N, u32 n)
{
if (bn_sub_1(d, a, b, n))
bn_add_1(d, d, N, n);
}
static const u8 inv256[0x80] = {
0x01, 0xab, 0xcd, 0xb7, 0x39, 0xa3, 0xc5, 0xef,
0xf1, 0x1b, 0x3d, 0xa7, 0x29, 0x13, 0x35, 0xdf,
0xe1, 0x8b, 0xad, 0x97, 0x19, 0x83, 0xa5, 0xcf,
0xd1, 0xfb, 0x1d, 0x87, 0x09, 0xf3, 0x15, 0xbf,
0xc1, 0x6b, 0x8d, 0x77, 0xf9, 0x63, 0x85, 0xaf,
0xb1, 0xdb, 0xfd, 0x67, 0xe9, 0xd3, 0xf5, 0x9f,
0xa1, 0x4b, 0x6d, 0x57, 0xd9, 0x43, 0x65, 0x8f,
0x91, 0xbb, 0xdd, 0x47, 0xc9, 0xb3, 0xd5, 0x7f,
0x81, 0x2b, 0x4d, 0x37, 0xb9, 0x23, 0x45, 0x6f,
0x71, 0x9b, 0xbd, 0x27, 0xa9, 0x93, 0xb5, 0x5f,
0x61, 0x0b, 0x2d, 0x17, 0x99, 0x03, 0x25, 0x4f,
0x51, 0x7b, 0x9d, 0x07, 0x89, 0x73, 0x95, 0x3f,
0x41, 0xeb, 0x0d, 0xf7, 0x79, 0xe3, 0x05, 0x2f,
0x31, 0x5b, 0x7d, 0xe7, 0x69, 0x53, 0x75, 0x1f,
0x21, 0xcb, 0xed, 0xd7, 0x59, 0xc3, 0xe5, 0x0f,
0x11, 0x3b, 0x5d, 0xc7, 0x49, 0x33, 0x55, 0xff,
};
static void bn_mon_muladd_dig(u8 *d, u8 *a, u8 b, u8 *N, u32 n)
{
u32 dig;
u32 i;
u8 z = -(d[n-1] + a[n-1]*b) * inv256[N[n-1]/2];
dig = d[n-1] + a[n-1]*b + N[n-1]*z;
dig >>= 8;
for (i = n - 2; i < n; i--) {
dig += d[i] + a[i]*b + N[i]*z;
d[i+1] = dig;
dig >>= 8;
}
d[0] = dig;
dig >>= 8;
if (dig)
bn_sub_1(d, d, N, n);
bn_reduce(d, N, n);
}
void bn_mon_mul(u8 *d, u8 *a, u8 *b, u8 *N, u32 n)
{
u8 t[512];
u32 i;
bn_zero(t, n);
for (i = n - 1; i < n; i--)
bn_mon_muladd_dig(t, a, b[i], N, n);
bn_copy(d, t, n);
}
void bn_to_mon(u8 *d, u8 *N, u32 n)
{
u32 i;
for (i = 0; i < 8*n; i++)
bn_add(d, d, d, N, n);
}
void bn_from_mon(u8 *d, u8 *N, u32 n)
{
u8 t[512];
bn_zero(t, n);
t[n-1] = 1;
bn_mon_mul(d, d, t, N, n);
}
static void bn_mon_exp(u8 *d, u8 *a, u8 *N, u32 n, u8 *e, u32 en)
{
u8 t[512];
u32 i;
u8 mask;
bn_zero(d, n);
d[n-1] = 1;
bn_to_mon(d, N, n);
for (i = 0; i < en; i++)
for (mask = 0x80; mask != 0; mask >>= 1) {
bn_mon_mul(t, d, d, N, n);
if ((e[i] & mask) != 0)
bn_mon_mul(d, t, a, N, n);
else
bn_copy(d, t, n);
}
}
void bn_mon_inv(u8 *d, u8 *a, u8 *N, u32 n)
{
u8 t[512], s[512];
bn_zero(s, n);
s[n-1] = 2;
bn_sub_1(t, N, s, n);
bn_mon_exp(d, a, N, n, t, n);
}

92
ext/libkirk/cmd Normal file
View File

@ -0,0 +1,92 @@
/usr/bin/c++
-std=gnu++0x
CMakeFiles/ppsspp.dir/home/artart78/prog/psp/ppsspp/android/jni/NativeApp.cpp.o
CMakeFiles/ppsspp.dir/home/artart78/prog/psp/ppsspp/android/jni/EmuScreen.cpp.o
CMakeFiles/ppsspp.dir/home/artart78/prog/psp/ppsspp/android/jni/MenuScreens.cpp.o
CMakeFiles/ppsspp.dir/home/artart78/prog/psp/ppsspp/android/jni/GamepadEmu.cpp.o
CMakeFiles/ppsspp.dir/home/artart78/prog/psp/ppsspp/android/jni/UIShader.cpp.o
CMakeFiles/ppsspp.dir/home/artart78/prog/psp/ppsspp/android/jni/ui_atlas.cpp.o
CMakeFiles/ppsspp.dir/home/artart78/prog/psp/ppsspp/native/base/PCMain.cpp.o
-o
ppsspp
-rdynamic
-L/usr/local/lib
-L/opt/local/lib
-L/usr/X11/lib
-Wl,-Bstatic
-lSDLmain
-Wl,-Bdynamic
-lSDL
-lpthread
-lGLU
-lGL
-lSM
-lICE
-lX11
-lXext
-lGLEW
kirk/libkirk.a
file/libfile.a
kirk/libkirk.a
math/liblin.a
kirk/libkirk.a
-lpng
kirk/libkirk.a
-lz
kirk/libkirk.a
gfx/libgfx.a
kirk/libkirk.a
gfx_es2/libgfx_es2.a
kirk/libkirk.a
etcpack/libetcdec.a
kirk/libkirk.a
image/libimage.a
kirk/libkirk.a
stb_image/libstb_image.a
kirk/libkirk.a
audio/libmixer.a
kirk/libkirk.a
net/libnet.a
kirk/libkirk.a
ui/libui.a
kirk/libkirk.a
profiler/libprofiler.a
kirk/libkirk.a
base/libtimeutil.a
kirk/libkirk.a
libzip/libzip.a
kirk/libkirk.a
base/libbase.a
kirk/libkirk.a
math/liblin.a
kirk/libkirk.a
vjson/libvjson.a
kirk/libkirk.a
stb_vorbis/libstb_vorbis.a
kirk/libkirk.a
sha1/libsha1.a
kirk/libkirk.a
jsonwriter/libjsonwriter.a
kirk/libkirk.a
Common/libcommon.a
kirk/libkirk.a
Core/libcore.a
kirk/libkirk.a
GPU/libgpu.a
kirk/libkirk.a
base/libbase.a
kirk/libkirk.a
Common/libcommon.a
kirk/libkirk.a
math/liblin.a
kirk/libkirk.a
gfx_es2/libgfx_es2.a
kirk/libkirk.a
file/libfile.a
kirk/libkirk.a
libzip/libzip.a
kirk/libkirk.a
gfx/libgfx.a
kirk/libkirk.a
-Wl,-rpath,/usr/local/lib:/opt/local/lib:/usr/X11/lib

463
ext/libkirk/ec.c Normal file
View File

@ -0,0 +1,463 @@
// Copyright 2007,2008,2010 Segher Boessenkool <segher@kernel.crashing.org>
// Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
// Modified for Kirk engine by setting single curve and internal function
// to support Kirk elliptic curve options.- July 2011
#include <string.h>
#include <stdio.h>
// Include definitions from kirk header
#include "kirk_engine.h"
struct point {
u8 x[20];
u8 y[20];
};
// Simplified for use by Kirk Engine since it has only 1 curve
u8 ec_p[20];
u8 ec_a[20];
u8 ec_b[20];
u8 ec_N[21];
struct point ec_G; // mon
struct point ec_Q; // mon
u8 ec_k[21];
void hex_dump(char *str, u8 *buf, int size)
{
int i;
if(str)
printf("%s:", str);
for(i=0; i<size; i++){
if((i%32)==0){
printf("\n%4X:", i);
}
printf(" %02X", buf[i]);
}
printf("\n\n");
}
static void elt_copy(u8 *d, u8 *a)
{
memcpy(d, a, 20);
}
static void elt_zero(u8 *d)
{
memset(d, 0, 20);
}
static int elt_is_zero(u8 *d)
{
u32 i;
for (i = 0; i < 20; i++)
if (d[i] != 0)
return 0;
return 1;
}
static void elt_add(u8 *d, u8 *a, u8 *b)
{
bn_add(d, a, b, ec_p, 20);
}
static void elt_sub(u8 *d, u8 *a, u8 *b)
{
bn_sub(d, a, b, ec_p, 20);
}
static void elt_mul(u8 *d, u8 *a, u8 *b)
{
bn_mon_mul(d, a, b, ec_p, 20);
}
static void elt_square(u8 *d, u8 *a)
{
elt_mul(d, a, a);
}
static void elt_inv(u8 *d, u8 *a)
{
u8 s[20];
elt_copy(s, a);
bn_mon_inv(d, s, ec_p, 20);
}
static void point_to_mon(struct point *p)
{
bn_to_mon(p->x, ec_p, 20);
bn_to_mon(p->y, ec_p, 20);
}
static void point_from_mon(struct point *p)
{
bn_from_mon(p->x, ec_p, 20);
bn_from_mon(p->y, ec_p, 20);
}
#if 0
static int point_is_on_curve(u8 *p)
{
u8 s[20], t[20];
u8 *x, *y;
x = p;
y = p + 20;
elt_square(t, x);
elt_mul(s, t, x);
elt_mul(t, x, ec_a);
elt_add(s, s, t);
elt_add(s, s, ec_b);
elt_square(t, y);
elt_sub(s, s, t);
return elt_is_zero(s);
}
#endif
static void point_zero(struct point *p)
{
elt_zero(p->x);
elt_zero(p->y);
}
static int point_is_zero(struct point *p)
{
return elt_is_zero(p->x) && elt_is_zero(p->y);
}
static void point_double(struct point *r, struct point *p)
{
u8 s[20], t[20];
struct point pp;
u8 *px, *py, *rx, *ry;
pp = *p;
px = pp.x;
py = pp.y;
rx = r->x;
ry = r->y;
if (elt_is_zero(py)) {
point_zero(r);
return;
}
elt_square(t, px); // t = px*px
elt_add(s, t, t); // s = 2*px*px
elt_add(s, s, t); // s = 3*px*px
elt_add(s, s, ec_a); // s = 3*px*px + a
elt_add(t, py, py); // t = 2*py
elt_inv(t, t); // t = 1/(2*py)
elt_mul(s, s, t); // s = (3*px*px+a)/(2*py)
elt_square(rx, s); // rx = s*s
elt_add(t, px, px); // t = 2*px
elt_sub(rx, rx, t); // rx = s*s - 2*px
elt_sub(t, px, rx); // t = -(rx-px)
elt_mul(ry, s, t); // ry = -s*(rx-px)
elt_sub(ry, ry, py); // ry = -s*(rx-px) - py
}
static void point_add(struct point *r, struct point *p, struct point *q)
{
u8 s[20], t[20], u[20];
u8 *px, *py, *qx, *qy, *rx, *ry;
struct point pp, qq;
pp = *p;
qq = *q;
px = pp.x;
py = pp.y;
qx = qq.x;
qy = qq.y;
rx = r->x;
ry = r->y;
if (point_is_zero(&pp)) {
elt_copy(rx, qx);
elt_copy(ry, qy);
return;
}
if (point_is_zero(&qq)) {
elt_copy(rx, px);
elt_copy(ry, py);
return;
}
elt_sub(u, qx, px);
if (elt_is_zero(u)) {
elt_sub(u, qy, py);
if (elt_is_zero(u))
point_double(r, &pp);
else
point_zero(r);
return;
}
elt_inv(t, u); // t = 1/(qx-px)
elt_sub(u, qy, py); // u = qy-py
elt_mul(s, t, u); // s = (qy-py)/(qx-px)
elt_square(rx, s); // rx = s*s
elt_add(t, px, qx); // t = px+qx
elt_sub(rx, rx, t); // rx = s*s - (px+qx)
elt_sub(t, px, rx); // t = -(rx-px)
elt_mul(ry, s, t); // ry = -s*(rx-px)
elt_sub(ry, ry, py); // ry = -s*(rx-px) - py
}
static void point_mul(struct point *d, u8 *a, struct point *b) // a is bignum
{
u32 i;
u8 mask;
point_zero(d);
for (i = 0; i < 21; i++)
for (mask = 0x80; mask != 0; mask >>= 1) {
point_double(d, d);
if ((a[i] & mask) != 0)
point_add(d, d, b);
}
}
// 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, u8 *k, u8 *hash)
{
u8 e[21];
u8 kk[21];
u8 m[21];
u8 R[21];
u8 S[21];
u8 minv[21];
struct point mG;
e[0] = 0;R[0] = 0;S[0] = 0;
memcpy(e + 1, hash, 20);
bn_reduce(e, ec_N, 21);
// Original removed for portability
//try_again:
//fp = fopen("/dev/random", "rb");
//if (fread(m, sizeof m, 1, fp) != 1)
//fail("reading random");
//fclose(fp);
//m[0] = 0;
//if (bn_compare(m, ec_N, 21) >= 0)
//goto try_again;
// R = (mG).x
// Added call back to kirk PRNG - July 2011
kirk_CMD14(m+1, 20);
m[0] = 0;
point_mul(&mG, m, &ec_G);
point_from_mon(&mG);
R[0] = 0;
elt_copy(R+1, mG.x);
// S = m**-1*(e + Rk) (mod N)
bn_copy(kk, k, 21);
bn_reduce(kk, ec_N, 21);
bn_to_mon(m, ec_N, 21);
bn_to_mon(e, ec_N, 21);
bn_to_mon(R, ec_N, 21);
bn_to_mon(kk, ec_N, 21);
bn_mon_mul(S, R, kk, ec_N, 21);
bn_add(kk, S, e, ec_N, 21);
bn_mon_inv(minv, m, ec_N, 21);
bn_mon_mul(S, minv, kk, ec_N, 21);
bn_from_mon(R, ec_N, 21);
bn_from_mon(S, ec_N, 21);
memcpy(outR,R+1,0x20);
memcpy(outS,S+1,0x20);
}
// Signing =
// r = k *G;
// s = x*r+m / k
// Verify =
// r/s * P = m/s * G
// Slightly modified to support kirk compatible signature input - July 2011
static int check_ecdsa(struct point *Q, u8 *inR, u8 *inS, u8 *hash)
{
u8 Sinv[21];
u8 e[21], R[21], S[21];
u8 w1[21], w2[21];
struct point r1, r2;
u8 rr[21];
e[0] = 0;
memcpy(e + 1, hash, 20);
bn_reduce(e, ec_N, 21);
R[0] = 0;
memcpy(R + 1, inR, 20);
bn_reduce(R, ec_N, 21);
S[0] = 0;
memcpy(S + 1, inS, 20);
bn_reduce(S, ec_N, 21);
bn_to_mon(R, ec_N, 21);
bn_to_mon(S, ec_N, 21);
bn_to_mon(e, ec_N, 21);
// make Sinv = 1/S
bn_mon_inv(Sinv, S, ec_N, 21);
// w1 = m * Sinv
bn_mon_mul(w1, e, Sinv, ec_N, 21);
// w2 = r * Sinv
bn_mon_mul(w2, R, Sinv, ec_N, 21);
// mod N both
bn_from_mon(w1, ec_N, 21);
bn_from_mon(w2, ec_N, 21);
// r1 = m/s * G
point_mul(&r1, w1, &ec_G);
// r2 = r/s * P
point_mul(&r2, w2, Q);
//r1 = r1 + r2
point_add(&r1, &r1, &r2);
point_from_mon(&r1);
rr[0] = 0;
memcpy(rr + 1, r1.x, 20);
bn_reduce(rr, ec_N, 21);
bn_from_mon(R, ec_N, 21);
bn_from_mon(S, ec_N, 21);
return (bn_compare(rr, R, 21) == 0);
}
// Modified from original to support kirk engine use - July 2011
void ec_priv_to_pub(u8 *k, u8 *Q)
{
struct point ec_temp;
bn_to_mon(k, ec_N, 21);
point_mul(&ec_temp, k, &ec_G);
point_from_mon(&ec_temp);
//bn_from_mon(k, ec_N, 21);
memcpy(Q,ec_temp.x,20);
memcpy(Q+20,ec_temp.y,20);
}
// Modified from original to support kirk engine use - July 2011
void ec_pub_mult(u8 *k, u8 *Q)
{
struct point ec_temp;
//bn_to_mon(k, ec_N, 21);
point_mul(&ec_temp, k, &ec_Q);
point_from_mon(&ec_temp);
//bn_from_mon(k, ec_N, 21);
memcpy(Q,ec_temp.x,20);
memcpy(Q+20,ec_temp.y,20);
}
// Simplified for use by Kirk Engine - NO LONGER COMPATIABLE WITH ORIGINAL VERSION - July 2011
int ecdsa_set_curve(u8* p,u8* a,u8* b,u8* N,u8* Gx,u8* Gy)
{
memcpy(ec_p,p,20);
memcpy(ec_a,a,20);
memcpy(ec_b,b,20);
memcpy(ec_N,N,21);
bn_to_mon(ec_a, ec_p, 20);
bn_to_mon(ec_b, ec_p, 20);
memcpy(ec_G.x, Gx, 20);
memcpy(ec_G.y, Gy, 20);
point_to_mon(&ec_G);
return 0;
}
void ecdsa_set_pub(u8 *Q)
{
memcpy(ec_Q.x, Q, 20);
memcpy(ec_Q.y, Q+20, 20);
point_to_mon(&ec_Q);
}
void ecdsa_set_priv(u8 *ink)
{
u8 k[21];
k[0]=0;
memcpy(k+1,ink,20);
bn_reduce(k, ec_N, 21);
memcpy(ec_k, k, sizeof ec_k);
}
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)
{
generate_ecdsa(R, S, ec_k, hash);
}
int point_is_on_curve(u8 *p)
{
u8 s[20], t[20];
u8 *x, *y;
x = p;
y = p + 20;
elt_square(t, x);
elt_mul(s, t, x);// s = x^3
elt_mul(t, x, ec_a);
elt_add(s, s, t); //s = x^3 + a *x
elt_add(s, s, ec_b);//s = x^3 + a *x + b
elt_square(t, y); //t = y^2
elt_sub(s, s, t); // is s - t = 0?
hex_dump("S", s, 20);
hex_dump("T", t,20);
return elt_is_zero(s);
}
void dump_ecc(void) {
hex_dump("P", ec_p, 20);
hex_dump("a", ec_a, 20);
hex_dump("b", ec_b, 20);
hex_dump("N", ec_N, 21);
hex_dump("Gx", ec_G.x, 20);
hex_dump("Gy", ec_G.y, 20);
}

640
ext/libkirk/kirk_engine.c Normal file
View File

@ -0,0 +1,640 @@
/*
Draan proudly presents:
With huge help from community:
coyotebean, Davee, hitchhikr, kgsws, liquidzigong, Mathieulh, Proxima, SilverSpring
******************** KIRK-ENGINE ********************
An Open-Source implementation of KIRK (PSP crypto engine) algorithms and keys.
Includes also additional routines for hash forging.
********************
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "kirk_engine.h"
#include "AES.h"
#include "SHA1.h"
/* ------------------------- KEY VAULT ------------------------- */
u8 kirk1_key[] = {0x98, 0xC9, 0x40, 0x97, 0x5C, 0x1D, 0x10, 0xE8, 0x7F, 0xE6, 0x0E, 0xA3, 0xFD, 0x03, 0xA8, 0xBA};
u8 kirk7_key03[] = {0x98, 0x02, 0xC4, 0xE6, 0xEC, 0x9E, 0x9E, 0x2F, 0xFC, 0x63, 0x4C, 0xE4, 0x2F, 0xBB, 0x46, 0x68};
u8 kirk7_key04[] = {0x99, 0x24, 0x4C, 0xD2, 0x58, 0xF5, 0x1B, 0xCB, 0xB0, 0x61, 0x9C, 0xA7, 0x38, 0x30, 0x07, 0x5F};
u8 kirk7_key05[] = {0x02, 0x25, 0xD7, 0xBA, 0x63, 0xEC, 0xB9, 0x4A, 0x9D, 0x23, 0x76, 0x01, 0xB3, 0xF6, 0xAC, 0x17};
u8 kirk7_key0C[] = {0x84, 0x85, 0xC8, 0x48, 0x75, 0x08, 0x43, 0xBC, 0x9B, 0x9A, 0xEC, 0xA7, 0x9C, 0x7F, 0x60, 0x18};
u8 kirk7_key0D[] = {0xB5, 0xB1, 0x6E, 0xDE, 0x23, 0xA9, 0x7B, 0x0E, 0xA1, 0x7C, 0xDB, 0xA2, 0xDC, 0xDE, 0xC4, 0x6E};
u8 kirk7_key0E[] = {0xC8, 0x71, 0xFD, 0xB3, 0xBC, 0xC5, 0xD2, 0xF2, 0xE2, 0xD7, 0x72, 0x9D, 0xDF, 0x82, 0x68, 0x82};
u8 kirk7_key0F[] = {0x0A, 0xBB, 0x33, 0x6C, 0x96, 0xD4, 0xCD, 0xD8, 0xCB, 0x5F, 0x4B, 0xE0, 0xBA, 0xDB, 0x9E, 0x03};
u8 kirk7_key10[] = {0x32, 0x29, 0x5B, 0xD5, 0xEA, 0xF7, 0xA3, 0x42, 0x16, 0xC8, 0x8E, 0x48, 0xFF, 0x50, 0xD3, 0x71};
u8 kirk7_key11[] = {0x46, 0xF2, 0x5E, 0x8E, 0x4D, 0x2A, 0xA5, 0x40, 0x73, 0x0B, 0xC4, 0x6E, 0x47, 0xEE, 0x6F, 0x0A};
u8 kirk7_key12[] = {0x5D, 0xC7, 0x11, 0x39, 0xD0, 0x19, 0x38, 0xBC, 0x02, 0x7F, 0xDD, 0xDC, 0xB0, 0x83, 0x7D, 0x9D};
u8 kirk7_key38[] = {0x12, 0x46, 0x8D, 0x7E, 0x1C, 0x42, 0x20, 0x9B, 0xBA, 0x54, 0x26, 0x83, 0x5E, 0xB0, 0x33, 0x03};
u8 kirk7_key39[] = {0xC4, 0x3B, 0xB6, 0xD6, 0x53, 0xEE, 0x67, 0x49, 0x3E, 0xA9, 0x5F, 0xBC, 0x0C, 0xED, 0x6F, 0x8A};
u8 kirk7_key3A[] = {0x2C, 0xC3, 0xCF, 0x8C, 0x28, 0x78, 0xA5, 0xA6, 0x63, 0xE2, 0xAF, 0x2D, 0x71, 0x5E, 0x86, 0xBA};
u8 kirk7_key4B[] = {0x0C, 0xFD, 0x67, 0x9A, 0xF9, 0xB4, 0x72, 0x4F, 0xD7, 0x8D, 0xD6, 0xE9, 0x96, 0x42, 0x28, 0x8B}; //1.xx game eboot.bin
u8 kirk7_key53[] = {0xAF, 0xFE, 0x8E, 0xB1, 0x3D, 0xD1, 0x7E, 0xD8, 0x0A, 0x61, 0x24, 0x1C, 0x95, 0x92, 0x56, 0xB6};
u8 kirk7_key57[] = {0x1C, 0x9B, 0xC4, 0x90, 0xE3, 0x06, 0x64, 0x81, 0xFA, 0x59, 0xFD, 0xB6, 0x00, 0xBB, 0x28, 0x70};
u8 kirk7_key5D[] = {0x11, 0x5A, 0x5D, 0x20, 0xD5, 0x3A, 0x8D, 0xD3, 0x9C, 0xC5, 0xAF, 0x41, 0x0F, 0x0F, 0x18, 0x6F};
u8 kirk7_key63[] = {0x9C, 0x9B, 0x13, 0x72, 0xF8, 0xC6, 0x40, 0xCF, 0x1C, 0x62, 0xF5, 0xD5, 0x92, 0xDD, 0xB5, 0x82};
u8 kirk7_key64[] = {0x03, 0xB3, 0x02, 0xE8, 0x5F, 0xF3, 0x81, 0xB1, 0x3B, 0x8D, 0xAA, 0x2A, 0x90, 0xFF, 0x5E, 0x61};
u8 kirk16_key[] = {0x47, 0x5E, 0x09, 0xF4, 0xA2, 0x37, 0xDA, 0x9B, 0xEF, 0xFF, 0x3B, 0xC0, 0x77, 0x14, 0x3D, 0x8A};
/* ECC Curves for Kirk 1 and Kirk 0x11 */
// Common Curve paramters p and a
static u8 ec_p[20] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
static u8 ec_a[20] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC}; // mon
// Kirk 0xC,0xD,0x10,0x11,(likely 0x12)- Unique curve parameters for b, N, and base point G for Kirk 0xC,0xD,0x10,0x11,(likely 0x12) service
// Since public key is variable, it is not specified here
static u8 ec_b2[20] = {0xA6, 0x8B, 0xED, 0xC3, 0x34, 0x18, 0x02, 0x9C, 0x1D, 0x3C, 0xE3, 0x3B, 0x9A, 0x32, 0x1F, 0xCC, 0xBB, 0x9E, 0x0F, 0x0B};// mon
static u8 ec_N2[21] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xB5, 0xAE, 0x3C, 0x52, 0x3E, 0x63, 0x94, 0x4F, 0x21, 0x27};
static u8 Gx2[20] = {0x12, 0x8E, 0xC4, 0x25, 0x64, 0x87, 0xFD, 0x8F, 0xDF, 0x64, 0xE2, 0x43, 0x7B, 0xC0, 0xA1, 0xF6, 0xD5, 0xAF, 0xDE, 0x2C };
static u8 Gy2[20] = {0x59, 0x58, 0x55, 0x7E, 0xB1, 0xDB, 0x00, 0x12, 0x60, 0x42, 0x55, 0x24, 0xDB, 0xC3, 0x79, 0xD5, 0xAC, 0x5F, 0x4A, 0xDF };
// KIRK 1 - Unique curve parameters for b, N, and base point G
// Since public key is hard coded, it is also included
static u8 ec_b1[20] = {0x65, 0xD1, 0x48, 0x8C, 0x03, 0x59, 0xE2, 0x34, 0xAD, 0xC9, 0x5B, 0xD3, 0x90, 0x80, 0x14, 0xBD, 0x91, 0xA5, 0x25, 0xF9};
static u8 ec_N1[21] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xB5, 0xC6, 0x17, 0xF2, 0x90, 0xEA, 0xE1, 0xDB, 0xAD, 0x8F};
static u8 Gx1[20] = {0x22, 0x59, 0xAC, 0xEE, 0x15, 0x48, 0x9C, 0xB0, 0x96, 0xA8, 0x82, 0xF0, 0xAE, 0x1C, 0xF9, 0xFD, 0x8E, 0xE5, 0xF8, 0xFA };
static u8 Gy1[20] = {0x60, 0x43, 0x58, 0x45, 0x6D, 0x0A, 0x1C, 0xB2, 0x90, 0x8D, 0xE9, 0x0F, 0x27, 0xD7, 0x5C, 0x82, 0xBE, 0xC1, 0x08, 0xC0 };
static u8 Px1[20] = {0xED, 0x9C, 0xE5, 0x82, 0x34, 0xE6, 0x1A, 0x53, 0xC6, 0x85, 0xD6, 0x4D, 0x51, 0xD0, 0x23, 0x6B, 0xC3, 0xB5, 0xD4, 0xB9 };
static u8 Py1[20] = {0x04, 0x9D, 0xF1, 0xA0, 0x75, 0xC0, 0xE0, 0x4F, 0xB3, 0x44, 0x85, 0x8B, 0x61, 0xB7, 0x9B, 0x69, 0xA6, 0x3D, 0x2C, 0x39 };
/* ------------------------- KEY VAULT END ------------------------- */
/* ------------------------- INTERNAL STUFF ------------------------- */
typedef struct blah
{
u8 fuseid[8]; //0
u8 mesh[0x40]; //0x8
} kirk16_data; //0x48
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
/* ------------------------- INTERNAL STUFF END ------------------------- */
/* ------------------------- IMPLEMENTATION ------------------------- */
int kirk_CMD0(u8* outbuff, 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
int chk_size;
AES_ctx k1;
AES_ctx cmac_key;
u8 cmac_header_hash[16];
u8 cmac_data_hash[16];
if(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);
//Make sure data is 16 aligned
chk_size = header->data_size;
if(chk_size % 16) chk_size += 16 - (chk_size % 16);
//ENCRYPT DATA
AES_set_key(&k1, keys->AES, 128);
AES_cbc_encrypt(&k1, inbuff+sizeof(KIRK_CMD1_HEADER)+header->data_offset, (u8*)outbuff+sizeof(KIRK_CMD1_HEADER)+header->data_offset, chk_size);
//CMAC HASHES
AES_set_key(&cmac_key, keys->CMAC, 128);
AES_CMAC(&cmac_key, outbuff+0x60, 0x30, cmac_header_hash);
AES_CMAC(&cmac_key, outbuff+0x60, 0x30 + chk_size + header->data_offset, cmac_data_hash);
memcpy(header->CMAC_header_hash, cmac_header_hash, 16);
memcpy(header->CMAC_data_hash, cmac_data_hash, 16);
//ENCRYPT KEYS
AES_cbc_encrypt(&aes_kirk1, inbuff, outbuff, 16*2);
return KIRK_OPERATION_SUCCESS;
}
int kirk_CMD1(u8* outbuff, u8* inbuff, int size)
{
KIRK_CMD1_HEADER* header = (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(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
if(header->ecdsa_hash == 1)
{
SHA_CTX sha;
KIRK_CMD1_ECDSA_HEADER* eheader = (KIRK_CMD1_ECDSA_HEADER*) inbuff;
u8 kirk1_pub[40];
u8 header_hash[20];u8 data_hash[20];
ecdsa_set_curve(ec_p,ec_a,ec_b1,ec_N1,Gx1,Gy1);
memcpy(kirk1_pub,Px1,20);
memcpy(kirk1_pub+20,Py1,20);
ecdsa_set_pub(kirk1_pub);
//Hash the Header
SHAInit(&sha);
SHAUpdate(&sha, (u8*)eheader+0x60, 0x30);
SHAFinal(header_hash, &sha);
if(!ecdsa_verify(header_hash,eheader->header_sig_r,eheader->header_sig_s)) {
return KIRK_HEADER_HASH_INVALID;
}
SHAInit(&sha);
SHAUpdate(&sha, (u8*)eheader+0x60, size-0x60);
SHAFinal(data_hash, &sha);
if(!ecdsa_verify(data_hash,eheader->data_sig_r,eheader->data_sig_s)) {
return KIRK_DATA_HASH_INVALID;
}
} else {
int ret = kirk_CMD10(inbuff, size);
if(ret != KIRK_OPERATION_SUCCESS) return ret;
}
AES_set_key(&k1, keys.AES, 128);
AES_cbc_decrypt(&k1, inbuff+sizeof(KIRK_CMD1_HEADER)+header->data_offset, outbuff, header->data_size);
return KIRK_OPERATION_SUCCESS;
}
int kirk_CMD4(u8* outbuff, u8* inbuff, int size)
{
KIRK_AES128CBC_HEADER *header = (KIRK_AES128CBC_HEADER*)inbuff;
u8* key;
AES_ctx aesKey;
if(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;
key = kirk_4_7_get_key(header->keyseed);
if(key == (u8*)KIRK_INVALID_SIZE) return KIRK_INVALID_SIZE;
//Set the key
AES_set_key(&aesKey, key, 128);
AES_cbc_encrypt(&aesKey, inbuff+sizeof(KIRK_AES128CBC_HEADER), outbuff+sizeof(KIRK_AES128CBC_HEADER), size);
return KIRK_OPERATION_SUCCESS;
}
int kirk_CMD7(u8* outbuff, u8* inbuff, int size)
{
KIRK_AES128CBC_HEADER *header = (KIRK_AES128CBC_HEADER*)inbuff;
u8* key;
AES_ctx aesKey;
if(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;
key = kirk_4_7_get_key(header->keyseed);
if(key == (u8*)KIRK_INVALID_SIZE) return KIRK_INVALID_SIZE;
//Set the key
AES_set_key(&aesKey, key, 128);
AES_cbc_decrypt(&aesKey, inbuff+sizeof(KIRK_AES128CBC_HEADER), outbuff, size);
return KIRK_OPERATION_SUCCESS;
}
int kirk_CMD10(u8* inbuff, int insize)
{
KIRK_CMD1_HEADER* header = (KIRK_CMD1_HEADER*)inbuff;
header_keys keys; //0-15 AES key, 16-31 CMAC key
u8 cmac_header_hash[16];
u8 cmac_data_hash[16];
AES_ctx cmac_key;
int chk_size;
if(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_set_key(&cmac_key, keys.CMAC, 128);
AES_CMAC(&cmac_key, inbuff+0x60, 0x30, cmac_header_hash);
//Make sure data is 16 aligned
chk_size = header->data_size;
if(chk_size % 16) chk_size += 16 - (chk_size % 16);
AES_CMAC(&cmac_key, inbuff+0x60, 0x30 + chk_size + header->data_offset, cmac_data_hash);
if(memcmp(cmac_header_hash, header->CMAC_header_hash, 16) != 0) return KIRK_HEADER_HASH_INVALID;
if(memcmp(cmac_data_hash, header->CMAC_data_hash, 16) != 0) return KIRK_DATA_HASH_INVALID;
return KIRK_OPERATION_SUCCESS;
}
return KIRK_SIG_CHECK_INVALID; //Checks for cmd 2 & 3 not included right now
}
int kirk_CMD11(u8* outbuff, 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(header->data_size == 0 || size == 0) return KIRK_DATA_SIZE_ZERO;
SHAInit(&sha);
SHAUpdate(&sha, inbuff+sizeof(KIRK_SHA1_HEADER), header->data_size);
SHAFinal(outbuff, &sha);
return KIRK_OPERATION_SUCCESS;
}
// 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) {
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);
ec_priv_to_pub(k, (u8*)keypair->public_key.x);
memcpy(keypair->private_key,k+1,0x14);
return KIRK_OPERATION_SUCCESS;
}
// 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) {
u8 k[0x15];
KIRK_CMD13_BUFFER * pointmult = (KIRK_CMD13_BUFFER *) inbuff;
k[0]=0;
if(outsize != 0x28) return KIRK_INVALID_SIZE;
if(insize != 0x3C) return KIRK_INVALID_SIZE;
ecdsa_set_curve(ec_p,ec_a,ec_b2,ec_N2,Gx2,Gy2);
ecdsa_set_pub((u8*)pointmult->public_key.x);
memcpy(k+1,pointmult->multiplier,0x14);
ec_pub_mult(k, outbuff);
return KIRK_OPERATION_SUCCESS;
}
int kirk_CMD14(u8 * outbuff, int outsize) {
u8 temp[0x104];
KIRK_SHA1_HEADER *header = (KIRK_SHA1_HEADER *) temp;
// Some randomly selected data for a "key" to add to each randomization
u8 key[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);
// This uses the standard C time function for portability.
curtime=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);
//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);
while(outsize)
{
int blockrem= outsize %0x14;
int block = outsize /0x14;
if(block)
{
memcpy(outbuff, PRNG_DATA, 0x14);
outbuff+=0x14;
outsize -= 0x14;
kirk_CMD14(outbuff, outsize);
} else {
if(blockrem)
{
memcpy(outbuff, PRNG_DATA, blockrem);
outsize -= blockrem;
}
}
}
return KIRK_OPERATION_SUCCESS;
}
void decrypt_kirk16_private(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;
/* set encryption key */
rijndael_set_key(&aes_ctx, kirk16_key, 128);
/* set the subkeys */
for (i = 0; i < 0x10; i++)
{
/* set to the fuseid */
subkey_2[i] = subkey_1[i] = keydata.fuseid[i % 8];
}
/* do aes crypto */
for (i = 0; i < 3; i++)
{
/* encrypt + decrypt */
rijndael_encrypt(&aes_ctx, subkey_1, subkey_1);
rijndael_decrypt(&aes_ctx, subkey_2, subkey_2);
}
/* set new key */
rijndael_set_key(&aes_ctx, subkey_1, 128);
/* now lets make the key mesh */
for (i = 0; i < 3; i++)
{
/* do encryption in group of 3 */
for (k = 0; k < 3; k++)
{
/* crypto */
rijndael_encrypt(&aes_ctx, subkey_2, subkey_2);
}
/* copy to out block */
memcpy(&keydata.mesh[i * 0x10], subkey_2, 0x10);
}
/* set the key to the mesh */
rijndael_set_key(&aes_ctx, &keydata.mesh[0x20], 128);
/* do the encryption routines for the aes key */
for (i = 0; i < 2; i++)
{
/* encrypt the data */
rijndael_encrypt(&aes_ctx, &keydata.mesh[0x10], &keydata.mesh[0x10]);
}
/* set the key to that mesh shit */
rijndael_set_key(&aes_ctx, &keydata.mesh[0x10], 128);
/* cbc decrypt the dA */
AES_cbc_decrypt((AES_ctx *)&aes_ctx, dA_enc, dA_out, 0x20);
}
void encrypt_kirk16_private(u8 *dA_out, u8 *dA_dec)
{
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;
/* set encryption key */
rijndael_set_key(&aes_ctx, kirk16_key, 128);
/* set the subkeys */
for (i = 0; i < 0x10; i++)
{
/* set to the fuseid */
subkey_2[i] = subkey_1[i] = keydata.fuseid[i % 8];
}
/* do aes crypto */
for (i = 0; i < 3; i++)
{
/* encrypt + decrypt */
rijndael_encrypt(&aes_ctx, subkey_1, subkey_1);
rijndael_decrypt(&aes_ctx, subkey_2, subkey_2);
}
/* set new key */
rijndael_set_key(&aes_ctx, subkey_1, 128);
/* now lets make the key mesh */
for (i = 0; i < 3; i++)
{
/* do encryption in group of 3 */
for (k = 0; k < 3; k++)
{
/* crypto */
rijndael_encrypt(&aes_ctx, subkey_2, subkey_2);
}
/* copy to out block */
memcpy(&keydata.mesh[i * 0x10], subkey_2, 0x10);
}
/* set the key to the mesh */
rijndael_set_key(&aes_ctx, &keydata.mesh[0x20], 128);
/* do the encryption routines for the aes key */
for (i = 0; i < 2; i++)
{
/* encrypt the data */
rijndael_encrypt(&aes_ctx, &keydata.mesh[0x10], &keydata.mesh[0x10]);
}
/* set the key to that mesh shit */
rijndael_set_key(&aes_ctx, &keydata.mesh[0x10], 128);
/* cbc encrypt the dA */
AES_cbc_encrypt((AES_ctx *)&aes_ctx, dA_dec, dA_out, 0x20);
}
int kirk_CMD16(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);
// 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);
return KIRK_OPERATION_SUCCESS;
}
// ECDSA Verify
// inbuff structure:
// 00 = public key (0x28 length)
// 28 = message hash (0x14 length)
// 3C = signature R (0x14 length)
// 50 = signature S (0x14 length)
int kirk_CMD17(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);
ecdsa_set_pub(sig->public_key.x);
// ecdsa_verify(u8 *hash, u8 *R, u8 *S)
if(ecdsa_verify(sig->message_hash,sig->signature.r,sig->signature.s)) {
return KIRK_OPERATION_SUCCESS;
} else {
return KIRK_SIG_CHECK_INVALID;
}
}
int kirk_init()
{
return kirk_init2((u8*)"Lazy Dev should have initialized!",33,0xBABEF00D, 0xDEADBEEF );;
}
int kirk_init2(u8 * rnd_seed, u32 seed_size, u32 fuseid_90, u32 fuseid_94) {
u8 temp[0x104];
KIRK_SHA1_HEADER *header = (KIRK_SHA1_HEADER *) temp;
// Another randomly selected data for a "key" to add to each randomization
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
if(seed_size > 0) {
u8 * seedbuf;
KIRK_SHA1_HEADER *seedheader;;
seedbuf=(u8*)malloc(seed_size+4);
seedheader= (KIRK_SHA1_HEADER *) seedbuf;
seedheader->data_size = seed_size;
kirk_CMD11(PRNG_DATA, seedbuf, seed_size+4);
free(seedbuf);
}
memcpy(temp+4, PRNG_DATA,0x14);
// This uses the standard C time function for portability.
curtime=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);
//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);
//Set Fuse ID
g_fuse90=fuseid_90;
g_fuse94=fuseid_94;
//Set KIRK1 main key
AES_set_key(&aes_kirk1, kirk1_key, 128);
is_kirk_initialized = 1;
return 0;
}
u8* kirk_4_7_get_key(int key_type)
{
switch(key_type)
{
case(0x03): return kirk7_key03; break;
case(0x04): return kirk7_key04; break;
case(0x05): return kirk7_key05; break;
case(0x0C): return kirk7_key0C; break;
case(0x0D): return kirk7_key0D; break;
case(0x0E): return kirk7_key0E; break;
case(0x0F): return kirk7_key0F; break;
case(0x10): return kirk7_key10; break;
case(0x11): return kirk7_key11; break;
case(0x12): return kirk7_key12; break;
case(0x38): return kirk7_key38; break;
case(0x39): return kirk7_key39; break;
case(0x3A): return kirk7_key3A; break;
case(0x4B): return kirk7_key4B; break;
case(0x53): return kirk7_key53; break;
case(0x57): return kirk7_key57; break;
case(0x5D): return kirk7_key5D; break;
case(0x63): return kirk7_key63; break;
case(0x64): return kirk7_key64; break;
default: return (u8*)KIRK_INVALID_SIZE; break; //need to get the real error code for that, placeholder now :)
}
}
int kirk_CMD1_ex(u8* outbuff, u8* inbuff, int size, KIRK_CMD1_HEADER* header)
{
u8* buffer = (u8*)malloc(size);
int ret;
memcpy(buffer, header, sizeof(KIRK_CMD1_HEADER));
memcpy(buffer+sizeof(KIRK_CMD1_HEADER), inbuff, header->data_size);
ret = kirk_CMD1(outbuff, buffer, size);
free(buffer);
return ret;
}
int sceUtilsBufferCopyWithRange(u8* outbuff, int outsize, u8* inbuff, int insize, int cmd)
{
switch(cmd)
{
case KIRK_CMD_DECRYPT_PRIVATE: return kirk_CMD1(outbuff, inbuff, insize); break;
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;
}
return -1;
}

246
ext/libkirk/kirk_engine.h Normal file
View File

@ -0,0 +1,246 @@
/*
Draan proudly presents:
With huge help from community:
coyotebean, Davee, hitchhikr, kgsws, liquidzigong, Mathieulh, Proxima, SilverSpring
******************** KIRK-ENGINE ********************
An Open-Source implementation of KIRK (PSP crypto engine) algorithms and keys.
Includes also additional routines for hash forging.
********************
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
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;
//Kirk return values
#define KIRK_OPERATION_SUCCESS 0
#define KIRK_NOT_ENABLED 1
#define KIRK_INVALID_MODE 2
#define KIRK_HEADER_HASH_INVALID 3
#define KIRK_DATA_HASH_INVALID 4
#define KIRK_SIG_CHECK_INVALID 5
#define KIRK_UNK_1 6
#define KIRK_UNK_2 7
#define KIRK_UNK_3 8
#define KIRK_UNK_4 9
#define KIRK_UNK_5 0xA
#define KIRK_UNK_6 0xB
#define KIRK_NOT_INITIALIZED 0xC
#define KIRK_INVALID_OPERATION 0xD
#define KIRK_INVALID_SEED_CODE 0xE
#define KIRK_INVALID_SIZE 0xF
#define KIRK_DATA_SIZE_ZERO 0x10
typedef struct
{
int mode; //0
int unk_4; //4
int unk_8; //8
int keyseed; //C
int data_size; //10
} KIRK_AES128CBC_HEADER; //0x14
typedef struct
{
u8 AES_key[16]; //0
u8 CMAC_key[16]; //10
u8 CMAC_header_hash[16]; //20
u8 CMAC_data_hash[16]; //30
u8 unused[32]; //40
u32 mode; //60
u8 ecdsa_hash; //64
u8 unk3[11]; //65
u32 data_size; //70
u32 data_offset; //74
u8 unk4[8]; //78
u8 unk5[16]; //80
} KIRK_CMD1_HEADER; //0x90
typedef struct
{
u8 AES_key[16]; //0
u8 header_sig_r[20]; //10
u8 header_sig_s[20]; //24
u8 data_sig_r[20]; //38
u8 data_sig_s[20]; //4C
u32 mode; //60
u8 ecdsa_hash; //64
u8 unk3[11]; //65
u32 data_size; //70
u32 data_offset; //74
u8 unk4[8]; //78
u8 unk5[16]; //80
} KIRK_CMD1_ECDSA_HEADER; //0x90
typedef struct
{
u8 r[0x14];
u8 s[0x14];
} ECDSA_SIG; //0x28
typedef struct
{
u8 x[0x14];
u8 y[0x14];
} ECDSA_POINT; //0x28
typedef struct
{
u32 data_size; //0
} KIRK_SHA1_HEADER; //4
typedef struct
{
u8 private_key[0x14];
ECDSA_POINT public_key;
} KIRK_CMD12_BUFFER;
typedef struct
{
u8 multiplier[0x14];
ECDSA_POINT public_key;
} KIRK_CMD13_BUFFER;
typedef struct
{
u8 enc_private[0x20]; //0
u8 message_hash[0x14]; //20
} KIRK_CMD16_BUFFER;//0x34
typedef struct
{
ECDSA_POINT public_key; //0
u8 message_hash[0x14]; //28
ECDSA_SIG signature; //3C
} KIRK_CMD17_BUFFER;//0x64
//mode passed to sceUtilsBufferCopyWithRange
#define KIRK_CMD_DECRYPT_PRIVATE 1
#define KIRK_CMD_2 2
#define KIRK_CMD_3 3
#define KIRK_CMD_ENCRYPT_IV_0 4
#define KIRK_CMD_ENCRYPT_IV_FUSE 5
#define KIRK_CMD_ENCRYPT_IV_USER 6
#define KIRK_CMD_DECRYPT_IV_0 7
#define KIRK_CMD_DECRYPT_IV_FUSE 8
#define KIRK_CMD_DECRYPT_IV_USER 9
#define KIRK_CMD_PRIV_SIGN_CHECK 10
#define KIRK_CMD_SHA1_HASH 11
#define KIRK_CMD_ECDSA_GEN_KEYS 12
#define KIRK_CMD_ECDSA_MULTIPLY_POINT 13
#define KIRK_CMD_PRNG 14
#define KIRK_CMD_15 15
#define KIRK_CMD_ECDSA_SIGN 16
#define KIRK_CMD_ECDSA_VERIFY 17
//"mode" in header
#define KIRK_MODE_CMD1 1
#define KIRK_MODE_CMD2 2
#define KIRK_MODE_CMD3 3
#define KIRK_MODE_ENCRYPT_CBC 4
#define KIRK_MODE_DECRYPT_CBC 5
//sceUtilsBufferCopyWithRange errors
#define SUBCWR_NOT_16_ALGINED 0x90A
#define SUBCWR_HEADER_HASH_INVALID 0x920
#define SUBCWR_BUFFER_TOO_SMALL 0x1000
/*
// Private Sig + Cipher
0x01: Super-Duper decryption (no inverse)
0x02: Encrypt Operation (inverse of 0x03)
0x03: Decrypt Operation (inverse of 0x02)
// Cipher
0x04: Encrypt Operation (inverse of 0x07) (IV=0)
0x05: Encrypt Operation (inverse of 0x08) (IV=FuseID)
0x06: Encrypt Operation (inverse of 0x09) (IV=UserDefined)
0x07: Decrypt Operation (inverse of 0x04)
0x08: Decrypt Operation (inverse of 0x05)
0x09: Decrypt Operation (inverse of 0x06)
// Sig Gens
0x0A: Private Signature Check (checks for private SCE sig)
0x0B: SHA1 Hash
0x0C: Mul1
0x0D: Mul2
0x0E: Random Number Gen
0x0F: (absolutely no idea could be KIRK initialization)
0x10: Signature Gen
// Sig Checks
0x11: Signature Check (checks for generated sigs)
0x12: Certificate Check (idstorage signatures)
*/
//kirk-like funcs
int kirk_CMD0(u8* outbuff, u8* inbuff, int size, int generate_trash);
int kirk_CMD1(u8* outbuff, u8* inbuff, int size);
int kirk_CMD4(u8* outbuff, u8* inbuff, int size);
int kirk_CMD7(u8* outbuff, u8* inbuff, int size);
int kirk_CMD10(u8* inbuff, int insize);
int kirk_CMD11(u8* outbuff, 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(u8* inbuff, int insize);
int kirk_init(); //CMD 0xF?
int kirk_init2(u8 *, u32, u32, u32);
//helper funcs
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);
//sce-like funcs
int sceUtilsSetFuseID(u8*fuse);
int 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);
// Prototypes for the Elliptic Curve and Big Number functions
int ecdsa_get_params(u32 type, u8 *p, u8 *a, u8 *b, u8 *N, u8 *Gx, u8 *Gy);
int ecdsa_set_curve(u8* p,u8* a,u8* b,u8* N,u8* Gx,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 ec_priv_to_pub(u8 *k, u8 *Q);
void ec_pub_mult(u8 *k, u8 *Q);
void bn_copy(u8 *d, u8 *a, u32 n);
int bn_compare(u8 *a, u8 *b, u32 n);
void bn_reduce(u8 *d, u8 *N, u32 n);
void bn_add(u8 *d, u8 *a, u8 *b, u8 *N, u32 n);
void bn_sub(u8 *d, u8 *a, u8 *b, u8 *N, u32 n);
void bn_to_mon(u8 *d, u8 *N, u32 n);
void bn_from_mon(u8 *d, u8 *N, u32 n);
void bn_mon_mul(u8 *d, u8 *a, u8 *b, u8 *N, u32 n);
void bn_mon_inv(u8 *d, u8 *a, u8 *N, u32 n);
void hex_dump(char *str, u8 *buf, int size);
#define round_up(x,n) (-(-(x) & -(n)))
#define array_size(x) (sizeof(x) / sizeof(*(x)))
#endif

View File

@ -164,7 +164,7 @@
<ProjectReference Include="..\native\native.vcxproj">
<Project>{e8b58922-9827-493d-81e0-4b6e6bd77171}</Project>
</ProjectReference>
<ProjectReference Include="..\zlib\zlib.vcxproj">
<ProjectReference Include="..\ext\zlib\zlib.vcxproj">
<Project>{f761046e-6c38-4428-a5f1-38391a37bb34}</Project>
</ProjectReference>
</ItemGroup>