Compare commits
No commits in common. "09bd2e4792bd0346991d37da13f7a3e667a8e3c0" and "800b6f28e1ac252edfc1e6b3ae21d71f552e7652" have entirely different histories.
09bd2e4792
...
800b6f28e1
@ -1,62 +0,0 @@
|
|||||||
#include <Windows.h>
|
|
||||||
|
|
||||||
DWORD NvidiaDebugLevel = 0;
|
|
||||||
|
|
||||||
__declspec(dllexport) int amvFinalize_Nvidia() { return 0; }
|
|
||||||
__declspec(dllexport) int amvGetAvailableDriverEx_Nvidia(LPVOID pGpuHandle, DWORD dwGpuHandleSize) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
__declspec(dllexport) int amvGetAvailableDriver_Nvidia() {
|
|
||||||
return amvGetAvailableDriverEx_Nvidia(NULL, 4);
|
|
||||||
}
|
|
||||||
__declspec(dllexport) int amvGetConnectedDisplaysEx_Nvidia(LPVOID pGpuHandle, DWORD dwGpuHandleSize,
|
|
||||||
LPBYTE displayType) {
|
|
||||||
// TODO: Find a use of this to figure out what we should spoof!
|
|
||||||
if (displayType) *displayType = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
__declspec(dllexport) int amvGetConnectedDisplays_Nvidia(LPBYTE displayType) {
|
|
||||||
return amvGetConnectedDisplays_Nvidia(NULL, 4, displayType);
|
|
||||||
}
|
|
||||||
__declspec(dllexport) int amvGetCurrentPstateEx_Nvidia(LPVOID pGpuHandle, DWORD dwGpuHandleSize,
|
|
||||||
DWORD* pPstate) {
|
|
||||||
// TODO: Find a use of this to figure out what we should spoof!
|
|
||||||
if (pPstate) *pPstate = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
__declspec(dllexport) int amvGetCurrentPstate_Nvidia(DWORD* pPstate) {
|
|
||||||
return amvGetCurrentPstateEx_Nvidia(NULL, 4, pPstate);
|
|
||||||
}
|
|
||||||
__declspec(dllexport) int amvGetamvNvidiaDebugLevel() { return NvidiaDebugLevel; }
|
|
||||||
__declspec(dllexport) char* amvGetamvNvidiaVersion() {
|
|
||||||
return "\namv_nvidia Ver.1.05 Build:Jul 22 2011 13:53:26\n";
|
|
||||||
}
|
|
||||||
__declspec(dllexport) int amvInitialize_Nvidia(LPVOID pGpuHandle, DWORD dwGpuHandleSize) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
__declspec(dllexport) int amvSetCustomDisplaySetting2ndEx_Nvidia(
|
|
||||||
LPVOID pGpuHandle, DWORD dwGpuHandleSize, LPWORD NV_SetCustomDisplaySetting) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
__declspec(dllexport) int amvSetCustomDisplaySetting2nd_Nvidia(LPVOID pGpuHandle) {
|
|
||||||
return amvSetCustomDisplaySetting2ndEx_Nvidia(NULL, 4, pGpuHandle);
|
|
||||||
}
|
|
||||||
__declspec(dllexport) int amvSetCustomDisplaySettingEx_Nvidia(LPVOID pGpuHandle,
|
|
||||||
DWORD dwGpuHandleSize,
|
|
||||||
LPWORD NV_SetCustomDisplaySetting) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
__declspec(dllexport) int amvSetCustomDisplaySetting_Nvidia(LPVOID pGpuHandle) {
|
|
||||||
return amvSetCustomDisplaySettingEx_Nvidia(NULL, 4, pGpuHandle);
|
|
||||||
}
|
|
||||||
__declspec(dllexport) int amvSetDisplayModeEx_Nvidia(LPVOID pGpuHandle, DWORD dwGpuHandleSize,
|
|
||||||
BYTE displayMode) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
__declspec(dllexport) int amvSetDisplayMode_Nvidia(BYTE displayMode) {
|
|
||||||
return amvSetDisplayModeEx_Nvidia(NULL, 4, displayMode);
|
|
||||||
}
|
|
||||||
__declspec(dllexport) int amvSetamvNvidiaDebugLevel(DWORD debugLevel) {
|
|
||||||
NvidiaDebugLevel = debugLevel;
|
|
||||||
return NvidiaDebugLevel;
|
|
||||||
}
|
|
@ -115,8 +115,6 @@ BOOL smbus_ds28cn01_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
|
|||||||
memcpy(&MAC_INPUT_BUFFER[4], USER_EEPROM[page], DS28CN01_EEPROM_PAGE_SIZE);
|
memcpy(&MAC_INPUT_BUFFER[4], USER_EEPROM[page], DS28CN01_EEPROM_PAGE_SIZE);
|
||||||
memcpy(&MAC_INPUT_BUFFER[36], &data[0], 4);
|
memcpy(&MAC_INPUT_BUFFER[36], &data[0], 4);
|
||||||
MAC_INPUT_BUFFER[40] = 0x40 | page;
|
MAC_INPUT_BUFFER[40] = 0x40 | page;
|
||||||
// TODO: Where did I get that the unique number is factored in?
|
|
||||||
// This seems like it would cause sums to calculate wrong!
|
|
||||||
memcpy(&MAC_INPUT_BUFFER[41], UNIQUE_NUMBER, 7);
|
memcpy(&MAC_INPUT_BUFFER[41], UNIQUE_NUMBER, 7);
|
||||||
memcpy(&MAC_INPUT_BUFFER[48], &SECRET[4], 4);
|
memcpy(&MAC_INPUT_BUFFER[48], &SECRET[4], 4);
|
||||||
memcpy(&MAC_INPUT_BUFFER[52], &data[4], 3);
|
memcpy(&MAC_INPUT_BUFFER[52], &data[4], 3);
|
||||||
|
@ -13,9 +13,8 @@ LOG_FACILITY _lf = {
|
|||||||
};
|
};
|
||||||
PLOG_FACILITY plf = &_lf;
|
PLOG_FACILITY plf = &_lf;
|
||||||
|
|
||||||
#define N2_IO_BUFFER 512
|
#define N2_IO_BUFFER 0x1000
|
||||||
|
|
||||||
BYTE n2_auth_level = 1;
|
|
||||||
BYTE n2_in_buffer[N2_IO_BUFFER];
|
BYTE n2_in_buffer[N2_IO_BUFFER];
|
||||||
WORD n2_in_pointer = 0;
|
WORD n2_in_pointer = 0;
|
||||||
BYTE n2_out_buffer[N2_IO_BUFFER];
|
BYTE n2_out_buffer[N2_IO_BUFFER];
|
||||||
@ -26,7 +25,7 @@ WORD n2_error_code = 0;
|
|||||||
BYTE n2_auth_key[20] = { 0x96, 0xed, 0x31, 0xb2, 0x28, 0x71, 0x05, 0xa5, 0xa3, 0x30,
|
BYTE n2_auth_key[20] = { 0x96, 0xed, 0x31, 0xb2, 0x28, 0x71, 0x05, 0xa5, 0xa3, 0x30,
|
||||||
0x54, 0x0f, 0x25, 0xbe, 0xd8, 0x51, 0xa5, 0xc8, 0x36, 0x21 };
|
0x54, 0x0f, 0x25, 0xbe, 0xd8, 0x51, 0xa5, 0xc8, 0x36, 0x21 };
|
||||||
|
|
||||||
BYTE n2_session_salt[20];
|
BYTE n2_session_nonce[20];
|
||||||
struct {
|
struct {
|
||||||
BYTE key[16];
|
BYTE key[16];
|
||||||
BYTE iv[16];
|
BYTE iv[16];
|
||||||
@ -68,8 +67,7 @@ typedef struct {
|
|||||||
} N2_KEYCHIP_INFO, *PN2_KEYCHIP_INFO;
|
} N2_KEYCHIP_INFO, *PN2_KEYCHIP_INFO;
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
N2_KEYCHIP_INFO n2_keychip_info = {
|
N2_KEYCHIP_INFO n2_keychip_info = { .m_KeyId = KEY_ID,
|
||||||
.m_KeyId = KEY_ID,
|
|
||||||
.m_Appboot = {
|
.m_Appboot = {
|
||||||
.m_Format = 1,
|
.m_Format = 1,
|
||||||
.m_GameId = GAME_ID,
|
.m_GameId = GAME_ID,
|
||||||
@ -80,14 +78,13 @@ N2_KEYCHIP_INFO n2_keychip_info = {
|
|||||||
.m_DvdFlag = 1,
|
.m_DvdFlag = 1,
|
||||||
.m_NetworkAddr =
|
.m_NetworkAddr =
|
||||||
(192 << 0) | (168 << 8) | (103 << 16) | (0 << 24),
|
(192 << 0) | (168 << 8) | (103 << 16) | (0 << 24),
|
||||||
},
|
} };
|
||||||
};
|
|
||||||
|
|
||||||
WORD n2_enable_session(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
|
WORD n2_enable_session(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
|
||||||
*nOut = 20;
|
*nOut = 20;
|
||||||
|
|
||||||
RAND_bytes(n2_session_salt, sizeof n2_session_salt);
|
RAND_bytes(n2_session_nonce, sizeof n2_session_nonce);
|
||||||
memcpy(dataOut, n2_session_salt, sizeof n2_session_salt);
|
memcpy(dataOut, n2_session_nonce, sizeof n2_session_nonce);
|
||||||
|
|
||||||
log_misc(plf, "Session open");
|
log_misc(plf, "Session open");
|
||||||
return N2_SUCCESS;
|
return N2_SUCCESS;
|
||||||
@ -100,8 +97,6 @@ WORD n2_set_auth_key(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut)
|
|||||||
mxkCryptDecryptAes128CBC(n2_enc_key.key, n2_enc_key.iv, dataIn, pt, sizeof pt);
|
mxkCryptDecryptAes128CBC(n2_enc_key.key, n2_enc_key.iv, dataIn, pt, sizeof pt);
|
||||||
memcpy(n2_auth_key, pt, sizeof n2_auth_key);
|
memcpy(n2_auth_key, pt, sizeof n2_auth_key);
|
||||||
|
|
||||||
n2_auth_level = 2;
|
|
||||||
|
|
||||||
return N2_SUCCESS;
|
return N2_SUCCESS;
|
||||||
}
|
}
|
||||||
WORD n2_set_enc_key(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
|
WORD n2_set_enc_key(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
|
||||||
@ -113,13 +108,11 @@ WORD n2_set_enc_key(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut)
|
|||||||
memcpy(n2_enc_key.key, pt, sizeof n2_enc_key.key);
|
memcpy(n2_enc_key.key, pt, sizeof n2_enc_key.key);
|
||||||
memcpy(n2_enc_key.iv, pt + sizeof n2_enc_key.key, sizeof n2_enc_key.iv);
|
memcpy(n2_enc_key.iv, pt + sizeof n2_enc_key.key, sizeof n2_enc_key.iv);
|
||||||
|
|
||||||
n2_auth_level = 3;
|
|
||||||
|
|
||||||
return N2_SUCCESS;
|
return N2_SUCCESS;
|
||||||
}
|
}
|
||||||
WORD n2_get_auth_level(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
|
WORD n2_get_auth_level(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
|
||||||
*nOut = 1;
|
*nOut = 1;
|
||||||
dataOut[0] = n2_auth_level;
|
dataOut[0] = 3; // TODO: ?
|
||||||
log_misc(plf, "Auth level get");
|
log_misc(plf, "Auth level get");
|
||||||
return N2_SUCCESS;
|
return N2_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -248,9 +241,6 @@ void n2_install_commands() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void do_n2_command(WORD tag, WORD paramSize, WORD command, LPBYTE data) {
|
void do_n2_command(WORD tag, WORD paramSize, WORD command, LPBYTE data) {
|
||||||
EVP_MD_CTX* ctx;
|
|
||||||
unsigned int outlen;
|
|
||||||
|
|
||||||
n2_install_commands();
|
n2_install_commands();
|
||||||
|
|
||||||
log_info(plf, "Processing command: %04x/%04x (%d bytes)", tag, command, paramSize);
|
log_info(plf, "Processing command: %04x/%04x (%d bytes)", tag, command, paramSize);
|
||||||
@ -267,39 +257,6 @@ void do_n2_command(WORD tag, WORD paramSize, WORD command, LPBYTE data) {
|
|||||||
WORD expectedExtraData = N2_CHECKSUM_SIZE + N2_HEADER_SIZE;
|
WORD expectedExtraData = N2_CHECKSUM_SIZE + N2_HEADER_SIZE;
|
||||||
if (tag == N2_TAG_RQU_AUTH_COMMAND) expectedExtraData += N2_AUTH_SIZE;
|
if (tag == N2_TAG_RQU_AUTH_COMMAND) expectedExtraData += N2_AUTH_SIZE;
|
||||||
|
|
||||||
unsigned char sha1sum[20];
|
|
||||||
ctx = EVP_MD_CTX_create();
|
|
||||||
EVP_DigestInit(ctx, EVP_sha1());
|
|
||||||
EVP_DigestUpdate(ctx, n2_in_buffer, N2_HEADER_SIZE + paramSize - expectedExtraData);
|
|
||||||
EVP_DigestFinal_ex(ctx, sha1sum, &outlen);
|
|
||||||
EVP_MD_CTX_destroy(ctx);
|
|
||||||
|
|
||||||
HMAC_CTX hmac_ctx;
|
|
||||||
if (tag == N2_TAG_RQU_COMMAND) {
|
|
||||||
if (memcmp(sha1sum, n2_in_buffer + paramSize - N2_CHECKSUM_SIZE, N2_CHECKSUM_SIZE) != 0) {
|
|
||||||
log_error(plf, "SHA1Sum chek failed!");
|
|
||||||
result = N2_SUMFAIL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unsigned char nonce[20];
|
|
||||||
memcpy_s(nonce, 20, n2_in_buffer + paramSize - N2_CHECKSUM_SIZE - N2_AUTH_SIZE, 20);
|
|
||||||
unsigned char hmac[20];
|
|
||||||
|
|
||||||
HMAC_CTX_init(&hmac_ctx);
|
|
||||||
HMAC_Init_ex(&hmac_ctx, auth_key, sizeof auth_key, EVP_sha1(), NULL);
|
|
||||||
HMAC_Update(&hmac_ctx, sha1sum, N2_CHECKSUM_SIZE);
|
|
||||||
HMAC_Update(&hmac_ctx, n2_session_salt, N2_CHECKSUM_SIZE);
|
|
||||||
HMAC_Update(&hmac_ctx, nonce, N2_CHECKSUM_SIZE);
|
|
||||||
HMAC_Final(&hmac_ctx, hmac, &outlen);
|
|
||||||
HMAC_CTX_cleanup(&hmac_ctx);
|
|
||||||
|
|
||||||
if (memcmp(hmac, n2_in_buffer + paramSize - N2_AUTH_SIZE, N2_AUTH_SIZE) != 0) {
|
|
||||||
log_error(plf, "HMAC check failed!");
|
|
||||||
result = N2_AUTHFAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == N2_SUCCESS) {
|
|
||||||
n2_command handler = N2_COMMANDS[command & 0xff];
|
n2_command handler = N2_COMMANDS[command & 0xff];
|
||||||
if (handler.handler == NULL) {
|
if (handler.handler == NULL) {
|
||||||
result = N2_BAD_ORDINAL;
|
result = N2_BAD_ORDINAL;
|
||||||
@ -311,13 +268,15 @@ void do_n2_command(WORD tag, WORD paramSize, WORD command, LPBYTE data) {
|
|||||||
result = (*handler.handler)(paramSize, n2_in_buffer + N2_HEADER_SIZE,
|
result = (*handler.handler)(paramSize, n2_in_buffer + N2_HEADER_SIZE,
|
||||||
n2_out_buffer + N2_HEADER_SIZE, &bodyLength);
|
n2_out_buffer + N2_HEADER_SIZE, &bodyLength);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
WORD paramSizeOut = bodyLength + expectedExtraData;
|
WORD paramSizeOut = bodyLength + expectedExtraData;
|
||||||
((PWORD)n2_out_buffer)[0] = fix_endian(tag + 2);
|
((PWORD)n2_out_buffer)[0] = fix_endian(tag + 2);
|
||||||
((PWORD)n2_out_buffer)[1] = fix_endian(paramSizeOut);
|
((PWORD)n2_out_buffer)[1] = fix_endian(paramSizeOut);
|
||||||
((PWORD)n2_out_buffer)[2] = fix_endian(result);
|
((PWORD)n2_out_buffer)[2] = fix_endian(result);
|
||||||
|
|
||||||
|
EVP_MD_CTX* ctx;
|
||||||
|
unsigned int outlen;
|
||||||
|
|
||||||
WORD fixed_command = fix_endian(command);
|
WORD fixed_command = fix_endian(command);
|
||||||
|
|
||||||
// Calculate a SHA1 of the packet, and append it
|
// Calculate a SHA1 of the packet, and append it
|
||||||
@ -332,16 +291,26 @@ void do_n2_command(WORD tag, WORD paramSize, WORD command, LPBYTE data) {
|
|||||||
// At this point: packet = header | data | SHA(header | command | data)
|
// At this point: packet = header | data | SHA(header | command | data)
|
||||||
|
|
||||||
if (tag == N2_TAG_RQU_AUTH_COMMAND) {
|
if (tag == N2_TAG_RQU_AUTH_COMMAND) {
|
||||||
// TODO: Further investigation might be needed here.
|
BYTE crypto_buffer[N2_CHECKSUM_SIZE];
|
||||||
// The following code checks out against mxkeychip, but repeating the
|
|
||||||
// packet sum twice feels wrong.
|
// Calculate a new SHA1 of the packet, including the SHA1 we just appeneded
|
||||||
|
// crypto_buffer = SHA1(header | command | data)
|
||||||
|
ctx = EVP_MD_CTX_create();
|
||||||
|
EVP_DigestInit(ctx, EVP_sha1());
|
||||||
|
EVP_DigestUpdate(ctx, n2_out_buffer, N2_HEADER_SIZE);
|
||||||
|
EVP_DigestUpdate(ctx, &fixed_command, 2);
|
||||||
|
EVP_DigestUpdate(ctx, n2_out_buffer + N2_HEADER_SIZE, bodyLength);
|
||||||
|
EVP_DigestFinal_ex(ctx, crypto_buffer, &outlen);
|
||||||
|
EVP_MD_CTX_destroy(ctx);
|
||||||
|
|
||||||
// Calculate an HMAC, and append it
|
// Calculate an HMAC, and append it
|
||||||
|
HMAC_CTX hmac_ctx;
|
||||||
HMAC_CTX_init(&hmac_ctx);
|
HMAC_CTX_init(&hmac_ctx);
|
||||||
HMAC_Init_ex(&hmac_ctx, auth_key, sizeof auth_key, EVP_sha1(), NULL);
|
HMAC_Init_ex(&hmac_ctx, auth_key, sizeof auth_key, EVP_sha1(), NULL);
|
||||||
|
|
||||||
// SHA1(header | command | data)
|
// SHA1(header | command | data)
|
||||||
HMAC_Update(&hmac_ctx, n2_out_buffer + N2_HEADER_SIZE + bodyLength, N2_CHECKSUM_SIZE);
|
HMAC_Update(&hmac_ctx, crypto_buffer, sizeof crypto_buffer);
|
||||||
|
// SHA1(header | auth | data)
|
||||||
HMAC_Update(&hmac_ctx, n2_out_buffer + N2_HEADER_SIZE + bodyLength, N2_CHECKSUM_SIZE);
|
HMAC_Update(&hmac_ctx, n2_out_buffer + N2_HEADER_SIZE + bodyLength, N2_CHECKSUM_SIZE);
|
||||||
// Request nonce
|
// Request nonce
|
||||||
HMAC_Update(&hmac_ctx, n2_in_buffer + paramSize - N2_AUTH_SIZE - N2_CHECKSUM_SIZE,
|
HMAC_Update(&hmac_ctx, n2_in_buffer + paramSize - N2_AUTH_SIZE - N2_CHECKSUM_SIZE,
|
||||||
@ -350,10 +319,6 @@ void do_n2_command(WORD tag, WORD paramSize, WORD command, LPBYTE data) {
|
|||||||
HMAC_Final(&hmac_ctx, n2_out_buffer + N2_HEADER_SIZE + bodyLength + N2_CHECKSUM_SIZE,
|
HMAC_Final(&hmac_ctx, n2_out_buffer + N2_HEADER_SIZE + bodyLength + N2_CHECKSUM_SIZE,
|
||||||
&outlen);
|
&outlen);
|
||||||
HMAC_CTX_cleanup(&hmac_ctx);
|
HMAC_CTX_cleanup(&hmac_ctx);
|
||||||
|
|
||||||
// Update session salt
|
|
||||||
memcpy_s(n2_session_salt, sizeof n2_session_salt,
|
|
||||||
n2_out_buffer + N2_HEADER_SIZE + bodyLength, N2_CHECKSUM_SIZE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,7 +376,6 @@ BOOL smbus_N2_write(ich9_cmd_t cmd, WORD code, BYTE nbytes, LPBYTE data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOL smbus_N2_read(ich9_cmd_t cmd, WORD code, BYTE nbytes, BYTE* data) {
|
BOOL smbus_N2_read(ich9_cmd_t cmd, WORD code, BYTE nbytes, BYTE* data) {
|
||||||
// TODO: Unaligned mxk reads poke into this for the final byte!
|
|
||||||
log_error(plf, "Unsupported read mode: %01x (%02x)", cmd, code);
|
log_error(plf, "Unsupported read mode: %01x (%02x)", cmd, code);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -64,22 +64,6 @@ LONG WINAPI FakeRtlGetVersion(PRTL_OSVERSIONINFOW lpVersionInformation) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: We should probably handle libamv_amd.dll at some point too
|
|
||||||
HMODULE WINAPI FakeLoadLibraryA(LPCSTR lpLibFileName) {
|
|
||||||
if (strcmp(lpLibFileName, "libamv_nvidia.dll") == 0) {
|
|
||||||
return TrueLoadLibraryA(MICELIB);
|
|
||||||
}
|
|
||||||
return TrueLoadLibraryA(lpLibFileName);
|
|
||||||
}
|
|
||||||
#define WIDEN2(x) L ## x
|
|
||||||
#define WIDEN(x) WIDEN2(x)
|
|
||||||
HMODULE WINAPI FakeLoadLibraryW(LPCWSTR lpLibFileName) {
|
|
||||||
if (wcscmp(lpLibFileName, L"libamv_nvidia.dll") == 0) {
|
|
||||||
return TrueLoadLibraryW(WIDEN(MICELIB));
|
|
||||||
}
|
|
||||||
return TrueLoadLibraryW(lpLibFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hook_system() {
|
void hook_system() {
|
||||||
// TODO: This should be part of drives/hooks.c
|
// TODO: This should be part of drives/hooks.c
|
||||||
hook("Kernel32.dll", "GetVolumeInformationW", FakeGetVolumeInformationW, NULL);
|
hook("Kernel32.dll", "GetVolumeInformationW", FakeGetVolumeInformationW, NULL);
|
||||||
@ -87,8 +71,6 @@ void hook_system() {
|
|||||||
// hook("Kernel32.dll", "GetVersionExA", FakeGetVersionExA, NULL);
|
// hook("Kernel32.dll", "GetVersionExA", FakeGetVersionExA, NULL);
|
||||||
// hook("Kernel32.dll", "GetProcAddress", FakeGetProcAddress, (void*)&TrueGetProcAddress);
|
// hook("Kernel32.dll", "GetProcAddress", FakeGetProcAddress, (void*)&TrueGetProcAddress);
|
||||||
// hook("Kernel32.dll", "GetModuleHandleA", FakeGetModuleHandleA, (void*)&TrueGetModuleHandleA);
|
// hook("Kernel32.dll", "GetModuleHandleA", FakeGetModuleHandleA, (void*)&TrueGetModuleHandleA);
|
||||||
hook("Kernel32.dll", "LoadLibraryA", FakeLoadLibraryA, (void*)&TrueLoadLibraryA);
|
|
||||||
hook("Kernel32.dll", "LoadLibraryW", FakeLoadLibraryW, (void*)&TrueLoadLibraryW);
|
|
||||||
|
|
||||||
// hook("ntdll.dll", "RtlGetVersion", FakeRtlGetVersion, NULL);
|
// hook("ntdll.dll", "RtlGetVersion", FakeRtlGetVersion, NULL);
|
||||||
|
|
||||||
|
@ -2,9 +2,7 @@
|
|||||||
|
|
||||||
#include "../common.h"
|
#include "../common.h"
|
||||||
|
|
||||||
FARPROC(WINAPI* TrueGetProcAddress)(HMODULE hModule, LPCSTR lpProcName);
|
FARPROC (*TrueGetProcAddress)(HMODULE hModule, LPCSTR lpProcName);
|
||||||
HMODULE(WINAPI* TrueGetModuleHandleA)(LPCSTR lpModuleName);
|
HMODULE (*TrueGetModuleHandleA)(LPCSTR lpModuleName);
|
||||||
HMODULE(WINAPI* TrueLoadLibraryA)(LPCSTR lpLibFileName);
|
|
||||||
HMODULE(WINAPI* TrueLoadLibraryW)(LPCWSTR lpLibFileName);
|
|
||||||
|
|
||||||
void hook_system();
|
void hook_system();
|
||||||
|
@ -8,8 +8,6 @@ shared_library(
|
|||||||
name_prefix: '',
|
name_prefix: '',
|
||||||
vs_module_defs: 'mice.def',
|
vs_module_defs: 'mice.def',
|
||||||
sources: [
|
sources: [
|
||||||
'amvStub/amv.c',
|
|
||||||
|
|
||||||
'util/misc.c',
|
'util/misc.c',
|
||||||
'util/hook.c',
|
'util/hook.c',
|
||||||
'util/path.c',
|
'util/path.c',
|
||||||
|
@ -9,9 +9,7 @@
|
|||||||
bool debug_wait = false;
|
bool debug_wait = false;
|
||||||
int boot_delay = 0;
|
int boot_delay = 0;
|
||||||
char exe_name[MAX_PATH + 1] = "";
|
char exe_name[MAX_PATH + 1] = "";
|
||||||
|
char commandline[MAX_PATH + 1] = "";
|
||||||
size_t nCommandLine = 256;
|
|
||||||
char* commandLine = NULL;
|
|
||||||
|
|
||||||
static void print_help(char* exe) {
|
static void print_help(char* exe) {
|
||||||
log_info(plfBoot, "Usage: %s [-h] [-t] [-b executable.exe] [-d]", exe);
|
log_info(plfBoot, "Usage: %s [-h] [-t] [-b executable.exe] [-d]", exe);
|
||||||
@ -71,13 +69,10 @@ static bool parse_cmdline(int argc, char* argv[]) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
size_t newLength = nCommandLine + 1 + strlen(argv[i]) + 1;
|
if (commandline[0] == 0)
|
||||||
if (newLength > nCommandLine) {
|
snprintf(commandline, sizeof commandline, "%s", argv[i]);
|
||||||
nCommandLine = newLength;
|
else
|
||||||
commandLine = realloc(commandLine, nCommandLine);
|
snprintf(commandline, sizeof commandline, "%s %s", commandline, argv[i]);
|
||||||
}
|
|
||||||
strcat_s(commandLine, nCommandLine, " ");
|
|
||||||
strcat_s(commandLine, nCommandLine, argv[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -181,13 +176,6 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
log_info(plfBoot, "Micetools version: %s", MICE_VERSION);
|
log_info(plfBoot, "Micetools version: %s", MICE_VERSION);
|
||||||
|
|
||||||
commandLine = malloc(nCommandLine);
|
|
||||||
if (commandLine == NULL) {
|
|
||||||
log_error(plfBoot, "Fatal: Failed to malloc(commandLine)");
|
|
||||||
return terminate(-1);
|
|
||||||
}
|
|
||||||
commandLine[0] = '\0';
|
|
||||||
|
|
||||||
CHAR workDir[MAX_PATH + 1];
|
CHAR workDir[MAX_PATH + 1];
|
||||||
GetCurrentDirectory(MAX_PATH, workDir);
|
GetCurrentDirectory(MAX_PATH, workDir);
|
||||||
log_info(plfBoot, "Current directory: %s", workDir);
|
log_info(plfBoot, "Current directory: %s", workDir);
|
||||||
@ -215,7 +203,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
spawn_pcp_processes();
|
spawn_pcp_processes();
|
||||||
|
|
||||||
log_info(plfBoot, "exec: %s %s", exe_name, commandLine);
|
log_info(plfBoot, "exec: %s %s", exe_name, commandline);
|
||||||
|
|
||||||
char micepath[MAX_PATH + 1];
|
char micepath[MAX_PATH + 1];
|
||||||
if (!locate_library(micepath, MAX_PATH + 1)) {
|
if (!locate_library(micepath, MAX_PATH + 1)) {
|
||||||
@ -228,30 +216,18 @@ int main(int argc, char* argv[]) {
|
|||||||
info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
||||||
SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &info, sizeof info);
|
SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &info, sizeof info);
|
||||||
|
|
||||||
size_t nFullCommandLine = nCommandLine + strlen(exe_name) + 1;
|
|
||||||
char* fullCommandLine = malloc(nFullCommandLine);
|
|
||||||
snprintf(fullCommandLine, nFullCommandLine, "%s %s", exe_name, commandLine);
|
|
||||||
free(commandLine);
|
|
||||||
|
|
||||||
char* extra_injections = MiceConfig.launcher.inject;
|
char* extra_injections = MiceConfig.launcher.inject;
|
||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
if (!start_and_inject(hJob, exe_name, fullCommandLine, micepath, debug_wait, boot_delay,
|
if (!start_and_inject(hJob, exe_name, commandline, micepath, debug_wait, boot_delay,
|
||||||
extra_injections, 0, &pi)) {
|
extra_injections, 0, &pi))
|
||||||
free(fullCommandLine);
|
|
||||||
return terminate(-1);
|
return terminate(-1);
|
||||||
}
|
|
||||||
free(fullCommandLine);
|
|
||||||
|
|
||||||
SetConsoleCtrlHandler(MiceHandlerRoutine, TRUE);
|
SetConsoleCtrlHandler(MiceHandlerRoutine, TRUE);
|
||||||
|
|
||||||
if (FAILED(WaitForSingleObject(pi.hProcess, INFINITE))) {
|
if (FAILED(WaitForSingleObject(pi.hProcess, INFINITE))) {
|
||||||
log_error(plfBoot, "Fatal: WaitForSingleObject failed: %03x", GetLastError());
|
log_error(plfBoot, "Fatal: WaitForSingleObject failed: %03x", GetLastError());
|
||||||
} else {
|
} else {
|
||||||
DWORD exitCode;
|
log_info(plfBoot, "Shutting down");
|
||||||
if (GetExitCodeProcess(pi.hProcess, &exitCode))
|
|
||||||
log_info(plfBoot, "Shutting down (ret:%d)", exitCode);
|
|
||||||
else
|
|
||||||
log_info(plfBoot, "Shutting down (failed to get exit code)");
|
|
||||||
CloseHandle(pi.hProcess);
|
CloseHandle(pi.hProcess);
|
||||||
}
|
}
|
||||||
return terminate(0);
|
return terminate(0);
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
AM_LIB_C_HEADER(amiCrc, AMI_CRC)
|
AM_LIB_C_HEADER(amiCrc, AMI_CRC)
|
||||||
|
|
||||||
void amiCrc32RCreateTable(uint32_t *table) {
|
void amiCrc32RCreateTable(unsigned int *table) {
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
uint32_t value = (~i & 1) - 1 & CRC32_POLYNOMIAL;
|
unsigned int value = (~i & 1) - 1 & CRC32_POLYNOMIAL;
|
||||||
value = ((i >> 1 ^ ~value) & 1) - 1 & CRC32_POLYNOMIAL ^ value >> 1;
|
value = ((i >> 1 ^ ~value) & 1) - 1 & CRC32_POLYNOMIAL ^ value >> 1;
|
||||||
value = ((i >> 2 ^ ~value) & 1) - 1 & CRC32_POLYNOMIAL ^ value >> 1;
|
value = ((i >> 2 ^ ~value) & 1) - 1 & CRC32_POLYNOMIAL ^ value >> 1;
|
||||||
value = ((i >> 3 ^ ~value) & 1) - 1 & CRC32_POLYNOMIAL ^ value >> 1;
|
value = ((i >> 3 ^ ~value) & 1) - 1 & CRC32_POLYNOMIAL ^ value >> 1;
|
||||||
@ -18,12 +18,13 @@ void amiCrc32RCreateTable(uint32_t *table) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t amiCrc32RGet(uint32_t *table, int length, void *data, uint32_t initial) {
|
unsigned int amiCrc32RGet(unsigned int *table, int length, unsigned char *data,
|
||||||
uint32_t value = ~initial;
|
unsigned int initial) {
|
||||||
|
unsigned int value = ~initial;
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
value = value >> 8 ^ table[(((unsigned char *)data)[0] ^ value) & 0xff];
|
value = value >> 8 ^ table[(data[0] ^ value) & 0xff];
|
||||||
length += -1;
|
length += -1;
|
||||||
((unsigned char *)data)++;
|
data++;
|
||||||
}
|
}
|
||||||
return ~value;
|
return ~value;
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "../_am.h"
|
#include "../_am.h"
|
||||||
|
|
||||||
AM_LIB_H_HEADER(amiCrc, AMI_CRC)
|
AM_LIB_H_HEADER(amiCrc, AMI_CRC)
|
||||||
|
|
||||||
typedef struct _AMI_CRC {
|
typedef struct _AMI_CRC {
|
||||||
uint32_t m_init;
|
unsigned int m_init;
|
||||||
uint32_t m_table[256];
|
unsigned int m_table[256];
|
||||||
} AMI_CRC;
|
} AMI_CRC;
|
||||||
|
|
||||||
void amiCrc32RCreateTable(uint32_t *table);
|
void amiCrc32RCreateTable(unsigned int *table);
|
||||||
uint32_t amiCrc32RGet(uint32_t *table, int length, void *data, uint32_t initial);
|
unsigned int amiCrc32RGet(unsigned int *table, int length, unsigned char *data,
|
||||||
|
unsigned int initial);
|
||||||
|
|
||||||
#define amiCrc32RInit() \
|
#define amiCrc32RInit() \
|
||||||
do { \
|
do { \
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
BOOL start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject, BOOL debug_wait,
|
BOOL start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject, BOOL debug_wait,
|
||||||
DWORD delay, LPCSTR extra_injections, DWORD flags,
|
DWORD delay, LPCSTR extra_injections, DWORD flags, LPPROCESS_INFORMATION lpProcessInformation);
|
||||||
LPPROCESS_INFORMATION lpProcessInformation);
|
|
||||||
|
|
||||||
#define MICELIB "mice.dll"
|
#define MICELIB "mice.dll"
|
||||||
|
@ -177,7 +177,7 @@ BOOL mxkNvramRead(unsigned short addr, unsigned char blocks, unsigned char* data
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool mxkValidString(const char* string, unsigned int length) {
|
bool mxkValidString(const char* string, unsigned int length) {
|
||||||
for (unsigned int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
char c = string[i];
|
char c = string[i];
|
||||||
if (isalnum(c)) continue;
|
if (isalnum(c)) continue;
|
||||||
if (c != '.' && c != '_' && c != '-' && c != ':' && c != '@' && c != '%' && c != '/' &&
|
if (c != '.' && c != '_' && c != '-' && c != ':' && c != '@' && c != '%' && c != '/' &&
|
||||||
@ -187,52 +187,7 @@ bool mxkValidString(const char* string, unsigned int length) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MXK_STATUS mxkGetKeychipIdFromN2(void) {
|
MXK_STATUS mxkInit() {
|
||||||
N2KeychipId_t kcId;
|
|
||||||
|
|
||||||
memset(&kcId, 0, sizeof kcId);
|
|
||||||
int err = mxkN2CmdReadKeychipID(&kcId);
|
|
||||||
if (err != 0) {
|
|
||||||
amiDebugLog("Error: mxkN2CmdReadKeychipID().ErrorCode %d", err);
|
|
||||||
return MXK_STATUS_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
amiCrc32RInit();
|
|
||||||
uint32_t crcCalc = amiCrc32RCalc((sizeof kcId.m_AppBoot) - 4, (LPBYTE)&kcId.m_AppBoot + 4, 0);
|
|
||||||
if (crcCalc != kcId.m_AppBoot.m_Crc) {
|
|
||||||
amiDebugLog("Error AppBootInfo CRC!!!");
|
|
||||||
return MXK_STATUS_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
crcCalc = amiCrc32RCalc(sizeof kcId - 4, (LPBYTE)&kcId + 4, 0);
|
|
||||||
if (crcCalc != kcId.m_Crc) {
|
|
||||||
amiDebugLog("Error KeychipID CRC!!!");
|
|
||||||
return MXK_STATUS_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// N2 keychip ID is a smaller, more compact, format than normal appboot. Restructure it to match
|
|
||||||
// before committing it to memory!
|
|
||||||
unsigned char keyId[16];
|
|
||||||
appboot_t appboot;
|
|
||||||
|
|
||||||
memcpy_s(keyId, sizeof keyId, kcId.m_KeyId, sizeof kcId.m_KeyId);
|
|
||||||
memcpy_s(&appboot, sizeof appboot, &kcId.m_AppBoot,
|
|
||||||
sizeof kcId.m_AppBoot - sizeof kcId.m_AppBoot.m_Seed);
|
|
||||||
memcpy_s(appboot.seed, sizeof appboot.seed, kcId.m_AppBoot.m_Seed,
|
|
||||||
sizeof kcId.m_AppBoot.m_Seed);
|
|
||||||
|
|
||||||
printf("Got N2 key ID: %.16s\n", keyId);
|
|
||||||
printf("Got N2 game ID: %.4s\n", kcId.m_AppBoot.m_GameId);
|
|
||||||
|
|
||||||
// ...but we're not actually committing it to memory at the moment!
|
|
||||||
// memcpy_s(&APPBOOT, 256, &appboot, sizeof appboot);
|
|
||||||
// memcpy_s(N2_KEYID, 16, keyId, 16);
|
|
||||||
// DAT_004adc95 = 0;
|
|
||||||
// DAT_004adda4 = 0;
|
|
||||||
return MXK_STATUS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
MXK_STATUS mxkInit(void) {
|
|
||||||
mxkVersionDirty = true;
|
mxkVersionDirty = true;
|
||||||
AppBoot.m_cacheDirty = true;
|
AppBoot.m_cacheDirty = true;
|
||||||
|
|
||||||
@ -248,6 +203,7 @@ MXK_STATUS mxkInit(void) {
|
|||||||
amiDebugLog("Error mxkExchengeAesKey!!");
|
amiDebugLog("Error mxkExchengeAesKey!!");
|
||||||
return MXK_STATUS_ERROR;
|
return MXK_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
// TODO: N2
|
||||||
if (mxkSmbusInit() != MXK_STATUS_OK) {
|
if (mxkSmbusInit() != MXK_STATUS_OK) {
|
||||||
amiDebugLog("Error mxkSmbusInit!!");
|
amiDebugLog("Error mxkSmbusInit!!");
|
||||||
return MXK_STATUS_ERROR;
|
return MXK_STATUS_ERROR;
|
||||||
@ -270,15 +226,9 @@ MXK_STATUS mxkInit(void) {
|
|||||||
// eeprom_playcount();
|
// eeprom_playcount();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mxkN2Init() != 0) {
|
// TODO:
|
||||||
amiDebugLog("Error mxkN2Init!!");
|
mxkN2CmdSetDeviceInfo();
|
||||||
return MXK_STATUS_ERROR;
|
mxkN2Authentication();
|
||||||
}
|
|
||||||
|
|
||||||
if (mxkGetKeychipIdFromN2() != 0) {
|
|
||||||
amiDebugLog("Error mxkGetKeychipIdFromN2!!");
|
|
||||||
return MXK_STATUS_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MXK_STATUS_OK;
|
return MXK_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#include "mxkCrypt.h"
|
#include "mxkCrypt.h"
|
||||||
|
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/hmac.h>
|
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
|
||||||
// These three should be initialised to null, and populated by mxkCryptInit, but we already know
|
// These three should be initialised to null, and populated by mxkCryptInit, but we already know
|
||||||
// their values and aren't trying to hide them from anyone! mxkCryptInit is still fully implemented,
|
// their values and aren't trying to hide them from anyone! mxkCryptInit is still fully implemented,
|
||||||
@ -153,8 +153,8 @@ void mxkSwapKeys() {
|
|||||||
memcpy(KEY_S, temp, 16);
|
memcpy(KEY_S, temp, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
MXK_STATUS mxkCryptEncryptAes128CBC(const unsigned char* key, const unsigned char* iv, void* ct,
|
MXK_STATUS mxkCryptEncryptAes128CBC(const unsigned char* key, const unsigned char* iv,
|
||||||
const void* pt, size_t nbytes) {
|
unsigned char* ct, const unsigned char* pt, size_t nbytes) {
|
||||||
if (key == NULL || iv == NULL || ct == NULL || pt == NULL) {
|
if (key == NULL || iv == NULL || ct == NULL || pt == NULL) {
|
||||||
amiDebugLog("Error: Invalid param.");
|
amiDebugLog("Error: Invalid param.");
|
||||||
return MXK_STATUS_INVALID_PARAM;
|
return MXK_STATUS_INVALID_PARAM;
|
||||||
@ -173,7 +173,7 @@ MXK_STATUS mxkCryptEncryptAes128CBC(const unsigned char* key, const unsigned cha
|
|||||||
}
|
}
|
||||||
|
|
||||||
MXK_STATUS mxkCryptDecryptAes128CBC(const unsigned char* key, const unsigned char* iv,
|
MXK_STATUS mxkCryptDecryptAes128CBC(const unsigned char* key, const unsigned char* iv,
|
||||||
const void* ct, void* pt, size_t nbytes) {
|
const unsigned char* ct, unsigned char* pt, size_t nbytes) {
|
||||||
if (key == NULL || iv == NULL || ct == NULL || pt == NULL) {
|
if (key == NULL || iv == NULL || ct == NULL || pt == NULL) {
|
||||||
amiDebugLog("Error: Invalid param.");
|
amiDebugLog("Error: Invalid param.");
|
||||||
return MXK_STATUS_INVALID_PARAM;
|
return MXK_STATUS_INVALID_PARAM;
|
||||||
|
@ -4,34 +4,23 @@
|
|||||||
#include "../ami/ami.h"
|
#include "../ami/ami.h"
|
||||||
#include "mxkDefs.h"
|
#include "mxkDefs.h"
|
||||||
|
|
||||||
#define SHA1_SUM_SIZE 20
|
|
||||||
#define HMAC_SUM_SIZE 20
|
|
||||||
#define HMAC_KEY_SIZE 20
|
|
||||||
|
|
||||||
typedef char Sha1Sum_t[SHA1_SUM_SIZE];
|
|
||||||
typedef char (*PSha1Sum_t)[SHA1_SUM_SIZE];
|
|
||||||
typedef char HmacSum_t[HMAC_SUM_SIZE];
|
|
||||||
typedef char (*PHmacSum_t)[HMAC_SUM_SIZE];
|
|
||||||
typedef char HmacKey_t[HMAC_SUM_SIZE];
|
|
||||||
typedef char (*PHmacKey_t)[HMAC_SUM_SIZE];
|
|
||||||
|
|
||||||
void mxkSetKeyS(unsigned char* key_s);
|
void mxkSetKeyS(unsigned char* key_s);
|
||||||
void mxkSetKeyR(unsigned char* key_r);
|
void mxkSetKeyR(unsigned char* key_r);
|
||||||
void mxkSwapKeys();
|
void mxkSwapKeys();
|
||||||
|
|
||||||
MXK_STATUS mxkCryptInit(void);
|
MXK_STATUS mxkCryptInit(void);
|
||||||
|
|
||||||
int mxkCryptCalcHashWithHmacSha1(PHmacKey_t key, PHmacSum_t md, size_t* nbuffer,
|
int mxkCryptCalcHashWithHmacSha1(void* key, unsigned char* md, size_t* nbuffer,
|
||||||
unsigned char* buffer, size_t nin);
|
unsigned char* buffer, size_t nin);
|
||||||
void mxkCryptCalcHashWithSha1(unsigned char* data, size_t nbytes, PSha1Sum_t sum);
|
void mxkCryptCalcHashWithSha1(unsigned char* data, size_t nbytes, unsigned char* sum);
|
||||||
|
|
||||||
void mxkCryptCreateDigest(void);
|
void mxkCryptCreateDigest(void);
|
||||||
void mxkCryptRsaSignVerify(void);
|
void mxkCryptRsaSignVerify(void);
|
||||||
|
|
||||||
MXK_STATUS mxkCryptDecryptAes128CBC(const unsigned char* key, const unsigned char* iv,
|
MXK_STATUS mxkCryptDecryptAes128CBC(const unsigned char* key, const unsigned char* iv,
|
||||||
const void* ct, void* pt, size_t nbytes);
|
const unsigned char* ct, unsigned char* pt, size_t nbytes);
|
||||||
MXK_STATUS mxkCryptEncryptAes128CBC(const unsigned char* key, const unsigned char* iv, void* ct,
|
MXK_STATUS mxkCryptEncryptAes128CBC(const unsigned char* key, const unsigned char* iv,
|
||||||
const void* pt, size_t nbytes);
|
unsigned char* pt, const unsigned char* ct, size_t nbytes);
|
||||||
|
|
||||||
MXK_STATUS mxkCryptDecryptData(const unsigned char* ct, unsigned char* pt);
|
MXK_STATUS mxkCryptDecryptData(const unsigned char* ct, unsigned char* pt);
|
||||||
MXK_STATUS mxkCryptEncryptData(unsigned char* ct, const unsigned char* pt);
|
MXK_STATUS mxkCryptEncryptData(unsigned char* ct, const unsigned char* pt);
|
||||||
|
@ -57,7 +57,7 @@ int mxkDsKeychipComputeMac(unsigned char page, void *challenge, unsigned char *m
|
|||||||
Sleep(16);
|
Sleep(16);
|
||||||
status = mxkDsWaitNotBusy(&INT_004ab34c);
|
status = mxkDsWaitNotBusy(&INT_004ab34c);
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
if (mxkSmbusI2CReadBlock(KC_DS_ADDRESS, DS28CN01_REG_MAC, mac, 20) != 0) {
|
if (!mxkSmbusI2CReadBlock(KC_DS_ADDRESS, DS28CN01_REG_MAC, mac, 20)) {
|
||||||
amiDebugLog("Error mxkSmbusI2CReadBlock()!!!");
|
amiDebugLog("Error mxkSmbusI2CReadBlock()!!!");
|
||||||
error = -8;
|
error = -8;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#include "mxkN2.h"
|
|
||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
@ -9,47 +7,30 @@
|
|||||||
#include "mxkCrypt.h"
|
#include "mxkCrypt.h"
|
||||||
#include "mxkSmbus.h"
|
#include "mxkSmbus.h"
|
||||||
|
|
||||||
|
#define N2_ADDR 0x30
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char m_Key[16];
|
unsigned char m_Key[16];
|
||||||
unsigned char m_IV[16];
|
unsigned char m_IV[16];
|
||||||
} AESKey_t;
|
} AESKey_t;
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned short m_Tag;
|
unsigned short m_Tag;
|
||||||
unsigned short m_ParamSize;
|
unsigned short m_ParamSize;
|
||||||
unsigned short m_Command;
|
unsigned short m_Command;
|
||||||
unsigned char m_Body[N2_DATA_MAX];
|
unsigned char m_Body[506];
|
||||||
} N2Packet_t;
|
} N2Packet_t;
|
||||||
typedef struct {
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
Sha1Sum_t m_ShaSum;
|
|
||||||
} rqu;
|
|
||||||
struct {
|
|
||||||
N2Nonce_t m_Nonce;
|
|
||||||
HmacSum_t m_Hmac;
|
|
||||||
} sign;
|
|
||||||
};
|
|
||||||
} N2PacketFooter_t;
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
BOOL MXK_HAS_INIT = FALSE;
|
BOOL MXK_HAS_INIT = FALSE;
|
||||||
BOOL MXK_N2_INIT = FALSE;
|
BOOL MXK_N2_INIT = FALSE;
|
||||||
#define CheckN2Init \
|
|
||||||
do { \
|
|
||||||
if (!MXK_N2_INIT) { \
|
|
||||||
amiDebugLog("Error: Uninitialized."); \
|
|
||||||
return -3; \
|
|
||||||
} \
|
|
||||||
} while (0);
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char m_Addr;
|
unsigned char m_Addr;
|
||||||
HmacKey_t m_HmacKey;
|
unsigned char m_HmacKey[20];
|
||||||
AESKey_t m_AESKey;
|
AESKey_t m_AESKey;
|
||||||
N2AuthKey_t m_AuthKey;
|
unsigned char m_AuthKey[20];
|
||||||
AESKey_t m_EncKey;
|
unsigned char m_EncKey[16];
|
||||||
HmacSum_t m_HmacSalt;
|
unsigned char Unk[16];
|
||||||
|
unsigned char m_HmacOut[20];
|
||||||
} N2DeviceInfo_t;
|
} N2DeviceInfo_t;
|
||||||
N2DeviceInfo_t N2DeviceInfo;
|
N2DeviceInfo_t N2DeviceInfo;
|
||||||
|
|
||||||
@ -60,16 +41,14 @@ unsigned char N2_KEY_HMAC[2][20] = {
|
|||||||
0x1d, 0x1e, 0x1f, 0x11, 0xee, 0xb0, 0xf4, 0xd4, 0x20, 0x24 }
|
0x1d, 0x1e, 0x1f, 0x11, 0xee, 0xb0, 0xf4, 0xd4, 0x20, 0x24 }
|
||||||
};
|
};
|
||||||
|
|
||||||
AESKey_t N2_KEY_AES[2] = {
|
AESKey_t N2_KEY_AES[2] = { { { 0xd7, 0xf6, 0x86, 0xfb, 0x63, 0x44, 0xff, 0xa5, 0x60, 0x9d, 0x4e,
|
||||||
{ { 0xd7, 0xf6, 0x86, 0xfb, 0x63, 0x44, 0xff, 0xa5, 0x60, 0x9d, 0x4e, 0xf0, 0x18, 0xe9, 0x45,
|
0xf0, 0x18, 0xe9, 0x45, 0xb4 },
|
||||||
0xb4 },
|
{ 0x12, 0x6c, 0xb1, 0xdb, 0x9e, 0x00, 0x8c, 0xc6, 0xae, 0xa1, 0x73,
|
||||||
{ 0x12, 0x6c, 0xb1, 0xdb, 0x9e, 0x00, 0x8c, 0xc6, 0xae, 0xa1, 0x73, 0xec, 0xe7, 0x2f, 0x5a,
|
0xec, 0xe7, 0x2f, 0x5a, 0xc4 } },
|
||||||
0xc4 } },
|
{ { 0xa1, 0x1a, 0xc4, 0x4d, 0xcd, 0x48, 0x4f, 0xed, 0x70, 0xcc, 0x3f,
|
||||||
{ { 0xa1, 0x1a, 0xc4, 0x4d, 0xcd, 0x48, 0x4f, 0xed, 0x70, 0xcc, 0x3f, 0x5d, 0x94, 0x5b, 0xbe,
|
0x5d, 0x94, 0x5b, 0xbe, 0xb3 },
|
||||||
0xb3 },
|
{ 0x9c, 0x5c, 0xba, 0x7f, 0xb0, 0x15, 0xc7, 0x69, 0xcb, 0xb4, 0x41,
|
||||||
{ 0x9c, 0x5c, 0xba, 0x7f, 0xb0, 0x15, 0xc7, 0x69, 0xcb, 0xb4, 0x41, 0x19, 0x97, 0x2b, 0x45,
|
0x19, 0x97, 0x2b, 0x45, 0x9f } } };
|
||||||
0x9f } },
|
|
||||||
};
|
|
||||||
|
|
||||||
int mxkN2CmdInit(void) {
|
int mxkN2CmdInit(void) {
|
||||||
if (MXK_N2_INIT) {
|
if (MXK_N2_INIT) {
|
||||||
@ -86,7 +65,7 @@ int mxkN2CmdSetDeviceInfo(void) {
|
|||||||
|
|
||||||
if (mxkN2CmdInit() != 0) return -5;
|
if (mxkN2CmdInit() != 0) return -5;
|
||||||
|
|
||||||
HmacKey_t hmacKey;
|
unsigned char hmacKey[20];
|
||||||
AESKey_t aesKey;
|
AESKey_t aesKey;
|
||||||
for (int i = 0; i < sizeof hmacKey; i++) hmacKey[i] = N2_KEY_HMAC[0][i] ^ N2_KEY_HMAC[1][i];
|
for (int i = 0; i < sizeof hmacKey; i++) hmacKey[i] = N2_KEY_HMAC[0][i] ^ N2_KEY_HMAC[1][i];
|
||||||
for (int i = 0; i < sizeof aesKey.m_Key; i++)
|
for (int i = 0; i < sizeof aesKey.m_Key; i++)
|
||||||
@ -109,18 +88,17 @@ int mxkN2CmdSetDeviceInfo(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Better name
|
// TODO: Better name
|
||||||
void _randomBytes(void *buf, int nbytes) {
|
void _randomBytes(unsigned char *buf, int nbytes) {
|
||||||
FILETIME fileTime;
|
FILETIME fileTime;
|
||||||
amtime_t amTime;
|
amtime_t amTime;
|
||||||
|
|
||||||
for (int i = 0; i < nbytes; i++) {
|
for (int i = 0; i < nbytes; i++) {
|
||||||
amiTimerGet(&amTime);
|
amiTimerGet(&amTime);
|
||||||
GetSystemTimeAsFileTime(&fileTime);
|
GetSystemTimeAsFileTime(&fileTime);
|
||||||
((unsigned char *)buf)[i] =
|
buf[i] = (amTime.microseconds ^ fileTime.dwLowDateTime ^ fileTime.dwHighDateTime) & 0xff;
|
||||||
(amTime.microseconds ^ fileTime.dwLowDateTime ^ fileTime.dwHighDateTime) & 0xff;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void mxkN2GetPacketNonce(PN2Nonce_t nonce) { _randomBytes(nonce, 20); }
|
void mxkN2GetPacketNonce(unsigned char *nonce) { _randomBytes(nonce, 20); }
|
||||||
|
|
||||||
int mxkN2UtilVCatenateData(unsigned char *out, size_t *count, unsigned int numStreams,
|
int mxkN2UtilVCatenateData(unsigned char *out, size_t *count, unsigned int numStreams,
|
||||||
va_list args) {
|
va_list args) {
|
||||||
@ -132,11 +110,10 @@ int mxkN2UtilVCatenateData(unsigned char *out, size_t *count, unsigned int numSt
|
|||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
size_t max = *count;
|
size_t max = *count;
|
||||||
for (size_t i = 0; i < numStreams && i < max; i++) {
|
for (size_t i = 0; i < numStreams && i < max; i++) {
|
||||||
unsigned char *b = va_arg(args, unsigned char *);
|
|
||||||
size_t n = va_arg(args, size_t);
|
size_t n = va_arg(args, size_t);
|
||||||
if (offset + n > max) n = max - offset;
|
unsigned char *b = va_arg(args, unsigned char *);
|
||||||
memcpy(out + offset, b, n);
|
if (i + n > max) n = max - i;
|
||||||
offset += n;
|
memcpy(out + offset, b, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
*count = offset;
|
*count = offset;
|
||||||
@ -152,49 +129,46 @@ void mxkN2UtilCatenateData(unsigned char *concatinated, size_t *count, unsigned
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mxkN2UtilSha1Many(PSha1Sum_t sum, int numStreams, ...) {
|
void mxkN2UtilSha1Many(unsigned char *sum, int numStreams, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, numStreams);
|
va_start(args, numStreams);
|
||||||
|
|
||||||
Sha1Sum_t sumout;
|
unsigned char sumout[20];
|
||||||
unsigned char concatinated[0x200];
|
unsigned char concatinated[0x200];
|
||||||
size_t size = sizeof concatinated;
|
size_t size = sizeof concatinated;
|
||||||
|
|
||||||
mxkN2UtilVCatenateData(concatinated, &size, numStreams, args);
|
mxkN2UtilVCatenateData(concatinated, &size, numStreams, args);
|
||||||
mxkCryptCalcHashWithSha1(concatinated, size, &sumout);
|
mxkCryptCalcHashWithSha1(concatinated, size, sumout);
|
||||||
memcpy_s(sum, sizeof *sum, sumout, sizeof sumout);
|
memcpy_s(sum, 20, sumout, 20);
|
||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mxkN2UtilHmacPacket(PSha1Sum_t packetSha, PHmacSum_t hmacSalt, PN2Nonce_t nonce, PHmacKey_t key,
|
int mxkN2UtilHmacPacket(void *val1, unsigned char *sha1, void *nonce, void *key,
|
||||||
PHmacSum_t computedHash) {
|
unsigned char *hash_out) {
|
||||||
HmacSum_t hash;
|
unsigned char hash[20];
|
||||||
unsigned char data_in[sizeof *packetSha + sizeof *hmacSalt + sizeof *nonce];
|
unsigned char data_in[60];
|
||||||
|
|
||||||
size_t count = sizeof *packetSha + sizeof *hmacSalt + sizeof *nonce;
|
size_t count = 60;
|
||||||
size_t nout = HMAC_SUM_SIZE;
|
size_t nout = 20;
|
||||||
mxkN2UtilCatenateData(data_in, &count, 3, packetSha, sizeof *packetSha, hmacSalt,
|
mxkN2UtilCatenateData(data_in, &count, 3, val1, 20, sha1, 20, nonce, 20);
|
||||||
sizeof *hmacSalt, nonce, sizeof *nonce);
|
|
||||||
|
|
||||||
int err = mxkCryptCalcHashWithHmacSha1(key, &hash, &nout, data_in, count);
|
int iVar1 = mxkCryptCalcHashWithHmacSha1(key, hash, &nout, data_in, count);
|
||||||
if (err == -2 || nout != HMAC_SUM_SIZE) return -2;
|
if (iVar1 != -2 && nout == 20) {
|
||||||
|
memcpy(hash_out, hash, 20);
|
||||||
memcpy_s(computedHash, sizeof *computedHash, hash, HMAC_SUM_SIZE);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
int mxkN2CmdWriteData(unsigned char addr, void *data, unsigned short nbytes,
|
int mxkN2CmdWriteData(unsigned char addr, unsigned char *data, unsigned short nbytes,
|
||||||
unsigned short *nbytesOut) {
|
unsigned short *nbytesOut) {
|
||||||
unsigned int ptr_;
|
unsigned int ptr_;
|
||||||
unsigned char nstep;
|
unsigned char nstep;
|
||||||
int status;
|
int status;
|
||||||
unsigned short position;
|
unsigned short position;
|
||||||
|
|
||||||
if (mxkSmbusRequestMutex() != 0) {
|
if (mxkSmbusRequestMutex() != 0) return -6;
|
||||||
amiDebugLog("Error: mxkSmbusRequestMutex");
|
|
||||||
return -6;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = 0;
|
status = 0;
|
||||||
position = 0;
|
position = 0;
|
||||||
@ -204,14 +178,14 @@ int mxkN2CmdWriteData(unsigned char addr, void *data, unsigned short nbytes,
|
|||||||
if ((int)(nbytes - ptr_) < 5) {
|
if ((int)(nbytes - ptr_) < 5) {
|
||||||
nstep = (byte)(nbytes - ptr_);
|
nstep = (byte)(nbytes - ptr_);
|
||||||
if (nstep != 1) goto LAB_0040ae51;
|
if (nstep != 1) goto LAB_0040ae51;
|
||||||
status = mxkSmbusWriteByte(addr, 0xcc, ((unsigned char *)data)[ptr_]);
|
status = mxkSmbusWriteByte(addr, 0xcc, data[ptr_]);
|
||||||
} else {
|
} else {
|
||||||
nstep = 4;
|
nstep = 4;
|
||||||
LAB_0040ae51:
|
LAB_0040ae51:
|
||||||
status = mxkSmbusI2CWriteBlock(addr, 0xcc, &((unsigned char *)data)[ptr_], nstep);
|
status = mxkSmbusI2CWriteBlock(addr, 0xcc, data + ptr_, nstep);
|
||||||
}
|
}
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
amiDebugLog("Error: Data write failed. Position %d. ErrorCode %d.", position,
|
amiDebugLog("Error: Data write failed. Position %d. ErrorCode %d.\n", position,
|
||||||
status);
|
status);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -222,410 +196,118 @@ int mxkN2CmdWriteData(unsigned char addr, void *data, unsigned short nbytes,
|
|||||||
}
|
}
|
||||||
*nbytesOut = position;
|
*nbytesOut = position;
|
||||||
|
|
||||||
if (mxkSmbusReleaseMutex() != 0) {
|
if (!mxkSmbusReleaseMutex()) return -6;
|
||||||
amiDebugLog("Error: mxkSmbusReleaseMutex");
|
|
||||||
return -6;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mxkN2CmdWriteCommand(PN2Nonce_t requestNonce, PHmacSum_t hmacSalt, N2Tag_t tag,
|
int mxkN2CmdWriteCommand(unsigned char *param_1, unsigned char *packet, unsigned short tag,
|
||||||
N2Command_t command, PHmacKey_t hmacKey, unsigned char addr,
|
unsigned short command, unsigned char *auth_key, unsigned char addr,
|
||||||
N2Byte_t *data, unsigned short nbytes) {
|
void *data, size_t nbytes) {
|
||||||
Sha1Sum_t sha1sum;
|
int iVar1;
|
||||||
N2Packet_t packet;
|
unsigned short real_tag;
|
||||||
int ret;
|
unsigned short paramsize;
|
||||||
|
|
||||||
|
N2Packet_t cmd;
|
||||||
|
|
||||||
if (data == NULL && nbytes != 0) return -2;
|
if (data == NULL && nbytes != 0) return -2;
|
||||||
|
|
||||||
N2PacketFooter_t *footer = (N2PacketFooter_t *)(packet.m_Body + nbytes);
|
memset(&cmd, 0, 0x200);
|
||||||
|
paramsize = (tag == N2_TAG_RQU_COMMAND ? 20 : 0) + 0x14 + (nbytes & 0xffff) + 6;
|
||||||
|
real_tag = (tag != N2_TAG_RQU_COMMAND) + 0xc1;
|
||||||
|
cmd.m_Tag = real_tag * 0x100 | real_tag >> 8;
|
||||||
|
cmd.m_ParamSize = (unsigned short)paramsize << 8 | (unsigned short)paramsize >> 8;
|
||||||
|
cmd.m_Command = command << 8 | command >> 8;
|
||||||
|
if (data != NULL) memcpy_s(cmd.m_Body, sizeof cmd.m_Body, data, nbytes);
|
||||||
|
|
||||||
ZeroMemory(&packet, sizeof packet);
|
// SHA1(header | data)
|
||||||
unsigned short paramsize =
|
unsigned char packet_sha[20];
|
||||||
N2_HEADER_SIZE + nbytes +
|
mxkN2UtilSha1Many(packet_sha, 1, &cmd, nbytes + 6);
|
||||||
(tag == N2_TAG_RQU_COMMAND ? N2_FOOTER_RQU_SIZE : N2_FOOTER_SIGN_SIZE);
|
|
||||||
|
|
||||||
N2Tag_t realTag = tag == N2_TAG_RQU_COMMAND ? N2_TAG_RQU_COMMAND : N2_TAG_RQU_AUTH_COMMAND;
|
|
||||||
packet.m_Tag = _byteswap_ushort(realTag);
|
|
||||||
packet.m_ParamSize = _byteswap_ushort(paramsize);
|
|
||||||
packet.m_Command = _byteswap_ushort(command);
|
|
||||||
|
|
||||||
if (data != NULL) memcpy_s(packet.m_Body, sizeof packet.m_Body, data, nbytes);
|
|
||||||
|
|
||||||
mxkN2UtilSha1Many(&sha1sum, 1, &packet, nbytes + N2_HEADER_SIZE);
|
|
||||||
|
|
||||||
if (tag == N2_TAG_RQU_COMMAND) {
|
if (tag == N2_TAG_RQU_COMMAND) {
|
||||||
memcpy_s(footer->rqu.m_ShaSum, sizeof footer->rqu.m_ShaSum, sha1sum, sizeof sha1sum);
|
memcpy(cmd.m_Body, packet_sha, 20);
|
||||||
} else {
|
} else {
|
||||||
if (requestNonce == NULL || hmacKey == NULL) return -2;
|
unsigned char nonce[20];
|
||||||
|
mxkN2GetPacketNonce(nonce);
|
||||||
|
memcpy(cmd.m_Body + nbytes, nonce, 20);
|
||||||
|
mxkN2UtilHmacPacket(packet_sha, param_1, nonce, auth_key, cmd.m_Body + nbytes + 20);
|
||||||
|
|
||||||
mxkN2GetPacketNonce(requestNonce);
|
puts("Dodgy HMAC");
|
||||||
memcpy_s(footer->sign.m_Nonce, sizeof footer->sign.m_Nonce, requestNonce,
|
exit(1);
|
||||||
sizeof *requestNonce);
|
|
||||||
|
|
||||||
mxkN2UtilHmacPacket(&sha1sum, hmacSalt, &footer->sign.m_Nonce, hmacKey,
|
|
||||||
&footer->sign.m_Hmac);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short nBytesOut;
|
unsigned short nWrote;
|
||||||
ret = mxkN2CmdWriteData(addr, &packet, paramsize, &nBytesOut);
|
iVar1 = mxkN2CmdWriteData(addr, (unsigned char *)&cmd, paramsize, &nWrote);
|
||||||
if (ret != 0) {
|
if (iVar1 == 0) {
|
||||||
amiDebugLog("Error: Data write failed. ErrorCode %d.", ret);
|
iVar1 = 0;
|
||||||
return -8;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mxkN2CmdReadData(unsigned char addr, N2Packet_t *lpPacket, unsigned short nReadSize,
|
|
||||||
unsigned short *lpBytesRead) {
|
|
||||||
int err;
|
|
||||||
*lpBytesRead = 0;
|
|
||||||
|
|
||||||
if (nReadSize < 4 || lpPacket == NULL) {
|
|
||||||
amiDebugLog("Error: Invalid param.");
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
if (mxkSmbusRequestMutex() != 0) return -6;
|
|
||||||
|
|
||||||
unsigned char *buffer = (unsigned char *)lpPacket;
|
|
||||||
|
|
||||||
// Read until m_ParamSize
|
|
||||||
err = mxkSmbusI2CReadBlock(addr, 0xc3, buffer, 4);
|
|
||||||
|
|
||||||
unsigned short readPosition = 4;
|
|
||||||
if (err == 0) {
|
|
||||||
unsigned short paramSize = _byteswap_ushort(lpPacket->m_ParamSize);
|
|
||||||
if (nReadSize < paramSize - 4) {
|
|
||||||
amiDebugLog("mxkSmbusI2CReadBlock data : %04X %04X", lpPacket->m_Tag,
|
|
||||||
lpPacket->m_ParamSize);
|
|
||||||
amiDebugLog("Error: Data size is too small.(readSize:%04X, m_paramSize:%04X)",
|
|
||||||
nReadSize, (lpPacket->m_ParamSize << 8 | lpPacket->m_ParamSize >> 8) - 4);
|
|
||||||
return -11;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (4 < paramSize) {
|
|
||||||
while (readPosition < paramSize) {
|
|
||||||
unsigned short blockSize = paramSize - readPosition;
|
|
||||||
if (blockSize > 4) blockSize = 4;
|
|
||||||
|
|
||||||
if (blockSize == 1)
|
|
||||||
err = mxkSmbusReadByte(addr, buffer + readPosition, 0xc3);
|
|
||||||
else
|
|
||||||
err = mxkSmbusI2CReadBlock(addr, 0xc3, buffer + readPosition, blockSize & 0xff);
|
|
||||||
|
|
||||||
if (err != 0) {
|
|
||||||
amiDebugLog("Error: Data read failed. Position %d. ErrorCode %d.", readPosition,
|
|
||||||
err);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
readPosition += blockSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*lpBytesRead = readPosition;
|
|
||||||
if (mxkSmbusReleaseMutex() != 0) {
|
|
||||||
amiDebugLog("Error: ReleaseMutex(). ErrorCode %d.", GetLastError());
|
|
||||||
return -6;
|
|
||||||
}
|
|
||||||
if (err) return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool mxkN2CmdIsValidOutParam(N2Packet_t *packet, unsigned tag, unsigned short paramSize) {
|
|
||||||
unsigned short tagPacket = _byteswap_ushort(packet->m_Tag);
|
|
||||||
unsigned short paramSizePacket = _byteswap_ushort(packet->m_ParamSize);
|
|
||||||
unsigned short returnCode = _byteswap_ushort(packet->m_Command);
|
|
||||||
if (tagPacket == tag && paramSizePacket == paramSize && returnCode == 0) return true;
|
|
||||||
|
|
||||||
amiDebugLog("tag: %04x, paramSize: %d, returnCode: %04x", tagPacket, paramSizePacket,
|
|
||||||
returnCode);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mxkN2CmdReadResponce(PN2Nonce_t requestNonce, PHmacSum_t hmacSalt, N2Tag_t tag,
|
|
||||||
N2Command_t command, PHmacKey_t hmacKey, unsigned char addr, void *bufOut,
|
|
||||||
unsigned short nOut) {
|
|
||||||
int ret;
|
|
||||||
unsigned short nBytesRead;
|
|
||||||
Sha1Sum_t sha1sum;
|
|
||||||
N2Packet_t packet;
|
|
||||||
|
|
||||||
ZeroMemory(&packet, sizeof packet);
|
|
||||||
unsigned short footerSize =
|
|
||||||
tag == N2_TAG_RQU_COMMAND ? N2_FOOTER_RQU_SIZE : N2_FOOTER_SIGN_SIZE;
|
|
||||||
ret = mxkN2CmdReadData(addr, &packet, nOut + N2_HEADER_SIZE + footerSize, &nBytesRead);
|
|
||||||
if (ret != 0) {
|
|
||||||
amiDebugLog("Error: Data read failed. ErrorCode %d.", ret);
|
|
||||||
return -7;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mxkN2CmdIsValidOutParam(
|
|
||||||
&packet, tag == N2_TAG_RQU_COMMAND ? N2_TAG_RSP_COMMAND : N2_TAG_RSP_AUTH_COMMAND,
|
|
||||||
nBytesRead)) {
|
|
||||||
amiDebugLog("Error: Invalid output parameter.");
|
|
||||||
return -9;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned short fixedCommand = _byteswap_ushort(command);
|
|
||||||
|
|
||||||
mxkN2UtilSha1Many(&sha1sum, 3, &packet, N2_HEADER_SIZE, &fixedCommand, sizeof fixedCommand,
|
|
||||||
packet.m_Body, nOut);
|
|
||||||
|
|
||||||
N2PacketFooter_t *footer = (N2PacketFooter_t *)(packet.m_Body + nOut);
|
|
||||||
|
|
||||||
if (tag == N2_TAG_RQU_COMMAND) {
|
|
||||||
if (memcmp(footer->rqu.m_ShaSum, sha1sum, sizeof sha1sum) != 0) {
|
|
||||||
amiDebugLog("Error: Invalid hash value.");
|
|
||||||
return -10;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (requestNonce == NULL || hmacKey == NULL) return -2;
|
amiDebugLog("Error: Data write failed. ErrorCode %d.", iVar1);
|
||||||
|
iVar1 = -8;
|
||||||
HmacSum_t computedHash;
|
|
||||||
mxkN2UtilHmacPacket(&sha1sum, &footer->sign.m_Nonce, requestNonce, hmacKey, &computedHash);
|
|
||||||
if (memcmp(footer->sign.m_Hmac, computedHash, sizeof computedHash) != 0) {
|
|
||||||
amiDebugLog("Error: Invalid hash value.");
|
|
||||||
return -10;
|
|
||||||
}
|
}
|
||||||
memcpy_s(requestNonce, sizeof *requestNonce, packet.m_Body + nOut, 20);
|
return iVar1;
|
||||||
|
|
||||||
if (hmacSalt != NULL)
|
|
||||||
memcpy_s(hmacSalt, sizeof *hmacSalt, &footer->sign.m_Nonce,
|
|
||||||
sizeof footer->sign.m_Nonce);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bufOut != NULL && nOut != 0) {
|
|
||||||
memcpy_s(bufOut, nOut, packet.m_Body,
|
|
||||||
((nBytesRead - footerSize) - N2_HEADER_SIZE) & 0xffff);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mxkN2CmdEnableSession(void) {
|
int mxkN2CmdEnableSession(void) {
|
||||||
N2Nonce_t nonce;
|
int ret;
|
||||||
|
unsigned char local_18[20];
|
||||||
|
|
||||||
CheckN2Init;
|
if (!MXK_N2_INIT) {
|
||||||
|
amiDebugLog("Error: Uninitialized.");
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
int err;
|
ret = mxkN2CmdWriteCommand(NULL, local_18, N2_TAG_RQU_COMMAND, N2_ORD_ENABLE_SESSION, NULL,
|
||||||
err = mxkN2CmdWriteCommand(&nonce, NULL, N2_TAG_RQU_COMMAND, N2_ORD_ENABLE_SESSION, NULL,
|
|
||||||
N2DeviceInfo.m_Addr, NULL, 0);
|
N2DeviceInfo.m_Addr, NULL, 0);
|
||||||
if (err != 0) return err;
|
if (ret != 0) return ret;
|
||||||
|
|
||||||
Sleep(32);
|
Sleep(32);
|
||||||
err = mxkN2CmdReadResponce(&nonce, NULL, N2_TAG_RQU_COMMAND, N2_ORD_ENABLE_SESSION, NULL,
|
// TODO: ASAP
|
||||||
N2DeviceInfo.m_Addr, &N2DeviceInfo.m_HmacSalt, 20);
|
// ret = mxkN2CmdReadResponce(local_18, NULL, N2_TAG_RQU_COMMAND, N2_ORD_ENABLE_SESSION, NULL,
|
||||||
if (err != 0) return err;
|
// N2DeviceInfo.m_Addr, N2DeviceInfo.m_HmacOut, 20);
|
||||||
|
if (ret != 0) return ret;
|
||||||
Sleep(16);
|
Sleep(16);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mxkN2CmdGetErrorCode(unsigned short *errorCode) {
|
|
||||||
N2Nonce_t nonce;
|
|
||||||
|
|
||||||
CheckN2Init;
|
|
||||||
|
|
||||||
int err;
|
|
||||||
err = mxkN2CmdWriteCommand(&nonce, NULL, N2_TAG_RQU_COMMAND, N2_ORD_GET_ERROR_CODE, NULL,
|
|
||||||
N2DeviceInfo.m_Addr, NULL, 0);
|
|
||||||
if (err != 0) return err;
|
|
||||||
|
|
||||||
Sleep(32);
|
|
||||||
unsigned short rawErrorCode;
|
|
||||||
err = mxkN2CmdReadResponce(&nonce, NULL, N2_TAG_RQU_COMMAND, N2_ORD_GET_ERROR_CODE, NULL,
|
|
||||||
N2DeviceInfo.m_Addr, &rawErrorCode, 2);
|
|
||||||
if (err != 0) return err;
|
|
||||||
|
|
||||||
Sleep(16);
|
|
||||||
*errorCode = _byteswap_ushort(rawErrorCode);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mxkN2CmdSetAuthKey(PN2AuthKey_t authKey) {
|
|
||||||
CheckN2Init;
|
|
||||||
|
|
||||||
unsigned char authKeyPt[32];
|
|
||||||
ZeroMemory(authKeyPt, sizeof authKeyPt);
|
|
||||||
unsigned char authKeyCt[32];
|
|
||||||
memcpy_s(authKeyPt, sizeof authKeyPt, authKey, sizeof *authKey);
|
|
||||||
mxkCryptEncryptAes128CBC(N2DeviceInfo.m_AESKey.m_Key, N2DeviceInfo.m_AESKey.m_IV, authKeyCt,
|
|
||||||
authKeyPt, sizeof authKeyPt);
|
|
||||||
|
|
||||||
N2Nonce_t nonce;
|
|
||||||
int err;
|
|
||||||
err = mxkN2CmdWriteCommand(&nonce, &N2DeviceInfo.m_HmacSalt, N2_TAG_RQU_AUTH_COMMAND,
|
|
||||||
N2_ORD_SET_AUTH_KEY, &N2DeviceInfo.m_HmacKey, N2DeviceInfo.m_Addr,
|
|
||||||
authKeyCt, sizeof authKeyCt);
|
|
||||||
if (err != 0) return err;
|
|
||||||
|
|
||||||
Sleep(96);
|
|
||||||
err = mxkN2CmdReadResponce(&nonce, &N2DeviceInfo.m_HmacSalt, N2_TAG_RQU_AUTH_COMMAND,
|
|
||||||
N2_ORD_SET_AUTH_KEY, &N2DeviceInfo.m_HmacKey, N2DeviceInfo.m_Addr,
|
|
||||||
NULL, 0);
|
|
||||||
if (err != 0) return err;
|
|
||||||
Sleep(16);
|
|
||||||
memcpy_s(N2DeviceInfo.m_AuthKey, sizeof N2DeviceInfo.m_AuthKey, authKey, sizeof *authKey);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mxkN2CmdSetEncKey(AESKey_t *encKey) {
|
|
||||||
CheckN2Init;
|
|
||||||
|
|
||||||
unsigned char encKeyCt[sizeof *encKey];
|
|
||||||
mxkCryptEncryptAes128CBC(N2DeviceInfo.m_AESKey.m_Key, N2DeviceInfo.m_AESKey.m_IV, encKeyCt,
|
|
||||||
encKey, sizeof encKeyCt);
|
|
||||||
|
|
||||||
N2Nonce_t requestNonce;
|
|
||||||
int err;
|
|
||||||
err = mxkN2CmdWriteCommand(&requestNonce, &N2DeviceInfo.m_HmacSalt, N2_TAG_RQU_AUTH_COMMAND,
|
|
||||||
N2_ORD_SET_ENC_KEY, &N2DeviceInfo.m_AuthKey, N2DeviceInfo.m_Addr,
|
|
||||||
encKeyCt, sizeof encKeyCt);
|
|
||||||
if (err != 0) return err;
|
|
||||||
|
|
||||||
Sleep(96);
|
|
||||||
err = mxkN2CmdReadResponce(&requestNonce, &N2DeviceInfo.m_HmacSalt, N2_TAG_RQU_AUTH_COMMAND,
|
|
||||||
N2_ORD_SET_ENC_KEY, &N2DeviceInfo.m_AuthKey, N2DeviceInfo.m_Addr,
|
|
||||||
NULL, 0);
|
|
||||||
if (err != 0) return err;
|
|
||||||
|
|
||||||
Sleep(16);
|
|
||||||
memcpy_s(&N2DeviceInfo.m_EncKey, sizeof N2DeviceInfo.m_EncKey, encKey, sizeof *encKey);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mxkN2CmdGetAuthLevel(unsigned char *authLevel) {
|
|
||||||
CheckN2Init;
|
|
||||||
|
|
||||||
unsigned char rawAuthlevel;
|
|
||||||
N2Nonce_t nonce;
|
|
||||||
|
|
||||||
int err;
|
|
||||||
err = mxkN2CmdWriteCommand(&nonce, NULL, N2_TAG_RQU_COMMAND, N2_ORD_GET_AUTH_LEVEL, NULL,
|
|
||||||
N2DeviceInfo.m_Addr, NULL, 0);
|
|
||||||
if (err != 0) return err;
|
|
||||||
Sleep(32);
|
|
||||||
err = mxkN2CmdReadResponce(&nonce, NULL, N2_TAG_RQU_COMMAND, N2_ORD_GET_AUTH_LEVEL, NULL,
|
|
||||||
N2DeviceInfo.m_Addr, &rawAuthlevel, 1);
|
|
||||||
if (err != 0) return err;
|
|
||||||
Sleep(16);
|
|
||||||
err = 0;
|
|
||||||
*authLevel = rawAuthlevel;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mxkN2GetErrorCode(void) {
|
|
||||||
unsigned short errorCode;
|
|
||||||
|
|
||||||
int err = mxkN2CmdGetErrorCode(&errorCode);
|
|
||||||
if (err != 0) {
|
|
||||||
amiDebugLog("Error: mxkN2CmdGetErrorCode(). ErrorCode %d", err);
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
amiDebugLog("N2 ErrorCode 0x%04X", errorCode);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int mxkN2CmdReadKeychipID(N2KeychipId_t *lpKeychipId) {
|
|
||||||
CheckN2Init;
|
|
||||||
|
|
||||||
N2Nonce_t nonce;
|
|
||||||
|
|
||||||
unsigned char readData[sizeof *lpKeychipId + 2];
|
|
||||||
|
|
||||||
N2Byte_t request[4];
|
|
||||||
request[0] = 0;
|
|
||||||
request[1] = 0;
|
|
||||||
request[2] = 0;
|
|
||||||
request[3] = sizeof *lpKeychipId;
|
|
||||||
|
|
||||||
int err;
|
|
||||||
err = mxkN2CmdWriteCommand(&nonce, &N2DeviceInfo.m_HmacSalt, N2_TAG_RQU_AUTH_COMMAND,
|
|
||||||
N2_ORD_READ_KEYCHIP_ID, &N2DeviceInfo.m_AuthKey, N2DeviceInfo.m_Addr,
|
|
||||||
request, sizeof request);
|
|
||||||
if (err != 0) return err;
|
|
||||||
Sleep(128);
|
|
||||||
err = mxkN2CmdReadResponce(&nonce, &N2DeviceInfo.m_HmacSalt, N2_TAG_RQU_AUTH_COMMAND,
|
|
||||||
N2_ORD_READ_KEYCHIP_ID, &N2DeviceInfo.m_AuthKey, N2DeviceInfo.m_Addr,
|
|
||||||
readData, sizeof readData);
|
|
||||||
|
|
||||||
if (err != 0) return err;
|
|
||||||
Sleep(16);
|
|
||||||
|
|
||||||
mxkCryptDecryptAes128CBC(N2DeviceInfo.m_EncKey.m_Key, N2DeviceInfo.m_EncKey.m_IV, readData + 2,
|
|
||||||
(unsigned char *)lpKeychipId, sizeof *lpKeychipId);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mxkN2Authentication(void) {
|
int mxkN2Authentication(void) {
|
||||||
N2AuthKey_t authKey;
|
// TODO: ASAP
|
||||||
AESKey_t enc_key;
|
// unsigned char auth_key[20];
|
||||||
|
// unsigned char enc_key[32];
|
||||||
|
|
||||||
if (!MXK_HAS_INIT) {
|
if (!MXK_HAS_INIT) {
|
||||||
amiDebugLog("No Init Error!!");
|
amiDebugLog("No Init Error!!");
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
int err;
|
int ErrorCode;
|
||||||
err = mxkN2CmdEnableSession();
|
|
||||||
if (err != 0) {
|
ErrorCode = mxkN2CmdEnableSession();
|
||||||
mxkN2GetErrorCode();
|
if (ErrorCode != 0) {
|
||||||
amiDebugLog("Error: mxkN2CmdEnableSession(). ErrorCode %d", err);
|
// mxkN2GetErrorCode();
|
||||||
|
amiDebugLog("Error: mxkN2CmdEnableSession(). ErrorCode %d", ErrorCode);
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char authLevel;
|
// _randomBytes(auth_key, sizeof auth_key);
|
||||||
mxkN2CmdGetAuthLevel(&authLevel);
|
// ErrorCode = mxkN2CmdSetAuthKey(auth_key);
|
||||||
printf("Achieved auth level: %d\n", authLevel);
|
// if (ErrorCode != 0) {
|
||||||
|
// mxkN2GetErrorCode();
|
||||||
|
// amiDebugLog("Error: mxkN2CmdSetAuthKey(). ErrorCode %d", ErrorCode);
|
||||||
|
// return -5;
|
||||||
|
// }
|
||||||
|
|
||||||
_randomBytes(authKey, sizeof authKey);
|
// _randomBytes(enc_key, sizeof enc_key);
|
||||||
err = mxkN2CmdSetAuthKey(&authKey);
|
// ErrorCode = mxkN2CmdSetEncKey(enc_key);
|
||||||
if (err != 0) {
|
// if (ErrorCode != 0) {
|
||||||
mxkN2GetErrorCode();
|
// mxkN2GetErrorCode();
|
||||||
amiDebugLog("Error: mxkN2CmdSetAuthKey(). ErrorCode %d", err);
|
// amiDebugLog("Error: mxkN2CmdSetEncKey().ErrorCode %d", ErrorCode);
|
||||||
|
// return -5;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// unsigned char auth_level;
|
||||||
|
// ErrorCode = mxkN2CmdGetAuthLevel(&auth_level);
|
||||||
|
// if (ErrorCode == 0 && auth_level == 3) return 0;
|
||||||
|
|
||||||
|
// mxkN2GetErrorCode();
|
||||||
|
// amiDebugLog("Error: mxkN2CmdGetAuthLevel().ErrorCode %d", ErrorCode);
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
mxkN2CmdGetAuthLevel(&authLevel);
|
|
||||||
printf("Achieved auth level: %d\n", authLevel);
|
|
||||||
|
|
||||||
_randomBytes(&enc_key, sizeof enc_key);
|
|
||||||
err = mxkN2CmdSetEncKey(&enc_key);
|
|
||||||
if (err != 0) {
|
|
||||||
mxkN2GetErrorCode();
|
|
||||||
amiDebugLog("Error: mxkN2CmdSetEncKey().ErrorCode %d", err);
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
mxkN2CmdGetAuthLevel(&authLevel);
|
|
||||||
printf("Achieved auth level: %d\n", authLevel);
|
|
||||||
|
|
||||||
// unsigned char authLevel;
|
|
||||||
err = mxkN2CmdGetAuthLevel(&authLevel);
|
|
||||||
if (err == 0 && authLevel == 3) return 0;
|
|
||||||
|
|
||||||
mxkN2GetErrorCode();
|
|
||||||
amiDebugLog("Error: mxkN2CmdGetAuthLevel().ErrorCode %d", err);
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mxkN2Exit(void) { MXK_N2_INIT = FALSE; }
|
|
||||||
|
|
||||||
int mxkN2Init(void) {
|
|
||||||
int err;
|
|
||||||
err = mxkN2CmdSetDeviceInfo();
|
|
||||||
if (err != 0) return err;
|
|
||||||
|
|
||||||
err = mxkN2Authentication();
|
|
||||||
if (err != 0) {
|
|
||||||
unsigned short errorCode;
|
|
||||||
err = mxkN2CmdGetErrorCode(&errorCode);
|
|
||||||
if (err != 0) {
|
|
||||||
amiDebugLog("Error: mxkN2CmdGetErrorCode(). ErrorCode %d", err);
|
|
||||||
} else {
|
|
||||||
amiDebugLog("N2 ErrorCode 0x%04X", errorCode);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
@ -1,72 +1,25 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <varargs.h>
|
#include <varargs.h>
|
||||||
|
|
||||||
#include "mxkCrypt.h"
|
void _randomBytes(unsigned char *buf, int nbytes);
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
typedef struct {
|
|
||||||
uint32_t m_Crc;
|
|
||||||
uint8_t m_Unk04[12];
|
|
||||||
uint8_t m_KeyId[16];
|
|
||||||
struct {
|
|
||||||
uint32_t m_Crc;
|
|
||||||
uint32_t m_FormatType;
|
|
||||||
uint8_t m_GameId[4];
|
|
||||||
uint8_t m_Region;
|
|
||||||
uint8_t m_ModelType;
|
|
||||||
uint8_t m_SystemFlags;
|
|
||||||
uint8_t Rsv0f;
|
|
||||||
uint8_t m_PlatformId[3];
|
|
||||||
uint8_t m_DvdFlag;
|
|
||||||
uint8_t m_NetworkAddr[4];
|
|
||||||
uint8_t Unk10[88];
|
|
||||||
uint8_t m_Seed[16];
|
|
||||||
} m_AppBoot;
|
|
||||||
} N2KeychipId_t;
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
#define N2_ADDR 0x30
|
|
||||||
|
|
||||||
#define N2_AUTH_KEY_SIZE 20
|
|
||||||
#define N2_NONCE_SIZE 20
|
|
||||||
#define N2_DATA_MAX 506
|
|
||||||
|
|
||||||
#define N2_FOOTER_RQU_SIZE SHA1_SUM_SIZE
|
|
||||||
#define N2_FOOTER_SIGN_SIZE (N2_NONCE_SIZE + HMAC_SUM_SIZE)
|
|
||||||
|
|
||||||
typedef char N2Nonce_t[N2_NONCE_SIZE];
|
|
||||||
typedef char N2AuthKey_t[N2_AUTH_KEY_SIZE];
|
|
||||||
typedef char (*PN2Nonce_t)[N2_NONCE_SIZE];
|
|
||||||
typedef char (*PN2AuthKey_t)[N2_AUTH_KEY_SIZE];
|
|
||||||
|
|
||||||
typedef unsigned short N2Tag_t;
|
|
||||||
typedef unsigned short N2Command_t;
|
|
||||||
typedef unsigned char N2Byte_t;
|
|
||||||
|
|
||||||
void _randomBytes(void *buf, int nbytes);
|
|
||||||
|
|
||||||
int mxkN2UtilVCatenateData(unsigned char *out, size_t *count, unsigned int numStreams,
|
int mxkN2UtilVCatenateData(unsigned char *out, size_t *count, unsigned int numStreams,
|
||||||
va_list args);
|
va_list args);
|
||||||
void mxkN2UtilCatenateData(unsigned char *concatinated, size_t *count, unsigned int numStreams,
|
void mxkN2UtilCatenateData(unsigned char *concatinated, size_t *count, unsigned int numStreams,
|
||||||
...);
|
...);
|
||||||
|
|
||||||
void mxkN2UtilSha1Many(PSha1Sum_t sum, int numStreams, ...);
|
void mxkN2UtilSha1Many(unsigned char *sum, int numStreams, ...);
|
||||||
int mxkN2UtilHmacPacket(PSha1Sum_t packetSha, PHmacSum_t hmacSalt, PN2Nonce_t nonce, PHmacKey_t key,
|
int mxkN2UtilHmacPacket(void *val1, unsigned char *sha1, void *nonce, void *key,
|
||||||
PHmacSum_t computedHash);
|
unsigned char *hash_out);
|
||||||
|
|
||||||
int mxkN2CmdWriteCommand(PN2Nonce_t nonce, PHmacSum_t hmacSalt, N2Tag_t tag, N2Command_t command,
|
int mxkN2CmdWriteCommand(unsigned char *param_1, unsigned char *packet, unsigned short tag,
|
||||||
PHmacKey_t hmacKey, unsigned char addr, N2Byte_t *data,
|
unsigned short command, unsigned char *auth_key, unsigned char addr,
|
||||||
unsigned short nbytes);
|
void *data, size_t nbytes);
|
||||||
|
|
||||||
int mxkN2CmdEnableSession(void);
|
int mxkN2CmdEnableSession(void);
|
||||||
int mxkN2CmdSetAuthKey(PN2AuthKey_t authKey);
|
int mxkN2CmdSetAuthKey(unsigned char* authKey);
|
||||||
|
|
||||||
int mxkN2CmdInit(void);
|
int mxkN2CmdInit(void);
|
||||||
int mxkN2CmdSetDeviceInfo(void);
|
int mxkN2CmdSetDeviceInfo(void);
|
||||||
int mxkN2Authentication(void);
|
int mxkN2Authentication(void);
|
||||||
int mxkN2CmdReadKeychipID(N2KeychipId_t *lpKeychipId);
|
|
||||||
|
|
||||||
int mxkN2Init(void);
|
|
||||||
void mxkN2Exit(void);
|
|
||||||
|
@ -228,7 +228,7 @@ int mxkSmbusI2CWriteCommand(unsigned char command_code, unsigned char *buffer, s
|
|||||||
return tries == 5 ? -9 : 0;
|
return tries == 5 ? -9 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mxkSmbusI2CReadBlock(unsigned char smbAddress, unsigned char block, unsigned char *buffer,
|
bool mxkSmbusI2CReadBlock(unsigned char smbAddress, unsigned char block, unsigned char *buffer,
|
||||||
unsigned char nbytes) {
|
unsigned char nbytes) {
|
||||||
DWORD nBytesReturned;
|
DWORD nBytesReturned;
|
||||||
smb_packet packet;
|
smb_packet packet;
|
||||||
@ -244,10 +244,10 @@ int mxkSmbusI2CReadBlock(unsigned char smbAddress, unsigned char block, unsigned
|
|||||||
if (!succ || nBytesReturned != sizeof packet) return false;
|
if (!succ || nBytesReturned != sizeof packet) return false;
|
||||||
if (packet.status == 0) {
|
if (packet.status == 0) {
|
||||||
memcpy(buffer, packet.data, nbytes);
|
memcpy(buffer, packet.data, nbytes);
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
if (packet.status != 24) return false;
|
if (packet.status != 24) return false;
|
||||||
Sleep(16);
|
Sleep(16);
|
||||||
}
|
}
|
||||||
return -8;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ int mxkSmbusI2CWriteCommand(unsigned char command_code, unsigned char *buffer, s
|
|||||||
|
|
||||||
int mxkSmbusI2CWriteBlock(unsigned char addr, unsigned char command, unsigned char *buffer,
|
int mxkSmbusI2CWriteBlock(unsigned char addr, unsigned char command, unsigned char *buffer,
|
||||||
unsigned char nbytes);
|
unsigned char nbytes);
|
||||||
int mxkSmbusI2CReadBlock(unsigned char smbAddress, unsigned char block, unsigned char *buffer,
|
bool mxkSmbusI2CReadBlock(unsigned char smbAddress, unsigned char block, unsigned char *buffer,
|
||||||
unsigned char nbytes);
|
unsigned char nbytes);
|
||||||
|
|
||||||
int mxkSmbusWriteByte(unsigned char v_addr, unsigned char command_code, unsigned char data);
|
int mxkSmbusWriteByte(unsigned char v_addr, unsigned char command_code, unsigned char data);
|
||||||
|
@ -16,7 +16,7 @@ void miceDumpKCPIC() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The following sequence is required, within 30 seconds, to avoid SBTR!
|
* The following sequence is required to avoid SBTR!
|
||||||
*
|
*
|
||||||
* amDongleSetupKeychip:
|
* amDongleSetupKeychip:
|
||||||
* keychip.appboot.systemflag=?&cache=0
|
* keychip.appboot.systemflag=?&cache=0
|
||||||
|
Loading…
Reference in New Issue
Block a user