OpenSSL implementation
This commit is contained in:
parent
df5fd8b05b
commit
f1988072a4
8 changed files with 74 additions and 119 deletions
|
@ -14,6 +14,10 @@ void FSkyPortalModule::ShutdownModule()
|
|||
{
|
||||
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
|
||||
// we call this function before unloading the module.
|
||||
|
||||
if (GEngine->GetEngineSubsystem<USkyPortalSubsystem>()) {
|
||||
GEngine->GetEngineSubsystem<USkyPortalSubsystem>()->Deinitialize();
|
||||
}
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
|
|
@ -9,7 +9,7 @@ uint32 FigureData::GetFigureID()
|
|||
int16_t OutFigureID = 0;
|
||||
|
||||
// The figure ID is stored in Block 1 of Sector 0 (i.e., data[1]), bytes 0 and 1 (16-bit integer, little-endian)
|
||||
OutFigureID = data[1][0] | // Least significant byte
|
||||
OutFigureID = decryptedData[1][0] | // Least significant byte
|
||||
(data[1][1] << 8); // Most significant byte, shifted left by 8 bits
|
||||
|
||||
ID = OutFigureID;// Return the 16-bit figure ID
|
||||
|
@ -25,64 +25,6 @@ uint32 FigureData::GetFigureID()
|
|||
|
||||
};
|
||||
|
||||
/*
|
||||
void FigureData::ReadData(uint8 index)
|
||||
{
|
||||
ClearData();
|
||||
for (uint8 i = 0; i < 64; i++)
|
||||
{
|
||||
GEngine->GetEngineSubsystem<USkyPortalSubsystem>();
|
||||
TArray<uint8> output = SkySubsystem->QueryBlock(index, i);
|
||||
|
||||
uint8[] blockData = new uint8[0x10];
|
||||
Array.Copy(output, 3, blockData, 0, 16);
|
||||
|
||||
// block 1 is sometimes a duplicate of block 0
|
||||
if (i == 1)
|
||||
{
|
||||
if (blockData.SequenceEqual(data[0]))
|
||||
{
|
||||
i -= 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Array.Copy(blockData, 0, data[i], 0, 16);
|
||||
|
||||
if (((i + 1) % 4 == 0) || i < 8)
|
||||
{
|
||||
Array.Copy(data[i], 0, decryptedData[i], 0, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8[] hashIn = new byte[0x56];
|
||||
data[0].CopyTo(hashIn, 0);
|
||||
data[1].CopyTo(hashIn, 0x10);
|
||||
hashIn[0x20] = i;
|
||||
HASH_CONST.CopyTo(hashIn, 0x21);
|
||||
|
||||
uint8[] key = MD5.Create().ComputeHash(hashIn);
|
||||
|
||||
uint8[] decrypted = new byte[0x10];
|
||||
|
||||
using (Aes aesAlg = Aes.Create())
|
||||
{
|
||||
aesAlg.Key = key;
|
||||
aesAlg.Mode = CipherMode.ECB;
|
||||
aesAlg.Padding = PaddingMode.Zeros;
|
||||
|
||||
ICryptoTransform decryptor = aesAlg.CreateDecryptor();
|
||||
|
||||
decrypted = decryptor.TransformFinalBlock(data[i], 0, data[i].Length);
|
||||
|
||||
}
|
||||
|
||||
Array.Copy(decrypted, 0, decryptedData[i], 0, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void FigureData::ClearData()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#include "SkyPortalIO.h"
|
||||
#include "Misc/AES.h"
|
||||
#include "Misc/ArchiveMD5.h"
|
||||
#include "Misc/ScopeLock.h"
|
||||
|
||||
#include "HAL/UnrealMemory.h"
|
||||
#include "openssl/aes.h"
|
||||
|
||||
|
||||
|
||||
DEFINE_LOG_CATEGORY(LogHIDApi);
|
||||
|
@ -281,12 +282,21 @@ FPortalStatusData ParsePortalStatus(const uint8* StatusResponse)
|
|||
}
|
||||
|
||||
|
||||
void DecryptAES128(uint8* OutData, const uint8* InData, const uint8* Key)
|
||||
{
|
||||
AES_KEY AesKey;
|
||||
// Set the decryption key (16 bytes for AES-128)
|
||||
AES_set_decrypt_key(Key, 128, &AesKey);
|
||||
|
||||
// Perform AES-128 decryption (ECB mode)
|
||||
AES_ecb_encrypt(InData, OutData, &AesKey, AES_DECRYPT);
|
||||
}
|
||||
|
||||
FigureData USkyPortalIO::ReadFigureBlocks(uint8 FigureIndex)
|
||||
{
|
||||
|
||||
FigureData FigureData;
|
||||
FigureData.dataError = false; // Initialize error flag
|
||||
FigureData TempFigureData;
|
||||
TempFigureData.dataError = false; // Initialize error flag
|
||||
|
||||
|
||||
|
||||
|
@ -297,12 +307,12 @@ FigureData USkyPortalIO::ReadFigureBlocks(uint8 FigureIndex)
|
|||
uint8* output = QueryBlock(FigureIndex, BlockIndex);
|
||||
|
||||
// Copy 16 bytes from the output, starting at the third byte
|
||||
FMemory::Memcpy(FigureData.data, output + 3, FIGURE_BLOCK_SIZE);
|
||||
FMemory::Memcpy(TempFigureData.data, output + 3, FIGURE_BLOCK_SIZE);
|
||||
|
||||
// Block 1 is sometimes a duplicate of block 0
|
||||
if (BlockIndex == 1)
|
||||
{
|
||||
if (FMemory::Memcmp(FigureData.data, FigureData.data[0], FIGURE_BLOCK_SIZE) == 0)
|
||||
if (FMemory::Memcmp(TempFigureData.data, TempFigureData.data[0], FIGURE_BLOCK_SIZE) == 0)
|
||||
{
|
||||
--BlockIndex; // Decrement index to reprocess
|
||||
continue;
|
||||
|
@ -312,15 +322,15 @@ FigureData USkyPortalIO::ReadFigureBlocks(uint8 FigureIndex)
|
|||
if (((BlockIndex + 1) % 4 == 0) || BlockIndex < 8)
|
||||
{
|
||||
// Direct copy from data to decryptedData for certain blocks
|
||||
FMemory::Memcpy(FigureData.decryptedData[BlockIndex], FigureData.data[BlockIndex], FIGURE_BLOCK_SIZE);
|
||||
FMemory::Memcpy(TempFigureData.decryptedData[BlockIndex], TempFigureData.data[BlockIndex], FIGURE_BLOCK_SIZE);
|
||||
|
||||
}
|
||||
else {
|
||||
/***** MD5 Hash Calculation *****/
|
||||
// Prepare the hash input buffer
|
||||
uint8 hashIn[0x56];
|
||||
FMemory::Memcpy(hashIn, FigureData.data[0], 16);
|
||||
FMemory::Memcpy(hashIn + 0x10, FigureData.data[1], 16);
|
||||
FMemory::Memcpy(hashIn, TempFigureData.data[0], 16);
|
||||
FMemory::Memcpy(hashIn + 0x10, TempFigureData.data[1], 16);
|
||||
hashIn[0x20] = BlockIndex;
|
||||
// Append the 35-byte constant
|
||||
FMemory::Memcpy(hashIn + 0x21, HASH_CONST, sizeof(HASH_CONST));
|
||||
|
@ -337,39 +347,14 @@ FigureData USkyPortalIO::ReadFigureBlocks(uint8 FigureIndex)
|
|||
FMemory::Memcpy(AesKey.Key, key, 16);
|
||||
|
||||
//TODO: FAES implementation in Unreal is AES-256. We need AES-128
|
||||
//FAES::DecryptData(FigureData.decryptedData[BlockIndex], FigureData.data[BlockIndex], 16, AesKey);
|
||||
//FAES::DecryptData(TempFigureData.decryptedData[BlockIndex], TempFigureData.data[BlockIndex], 16, AesKey);
|
||||
DecryptAES128(TempFigureData.decryptedData[BlockIndex], TempFigureData.data[BlockIndex], key);
|
||||
}
|
||||
|
||||
/*
|
||||
if (output[1] == (0x10 + 'Q')) // Successful query
|
||||
{
|
||||
// Extract the 16 bytes of block data
|
||||
for (int i = 3; i < 19; i++)
|
||||
{
|
||||
FigureData.data[BlockIndex][i] = output[i];
|
||||
}
|
||||
}
|
||||
else if (output[0] == 0x01) {
|
||||
FigureData.dataError = true;
|
||||
UE_LOG(LogSkyportalIO, Warning, TEXT("Error querying block %d from figure %d"), BlockIndex, FigureIndex);
|
||||
break;
|
||||
}
|
||||
|
||||
// Verify that the block index matches the requested block
|
||||
uint8 ReturnedBlockIndex = output[3];
|
||||
if (ReturnedBlockIndex != BlockIndex)
|
||||
{
|
||||
FigureData.dataError = true;
|
||||
UE_LOG(LogSkyportalIO, Warning, TEXT("Mismatched block index. Expected %d, got %d"), BlockIndex, ReturnedBlockIndex);
|
||||
break;
|
||||
}
|
||||
|
||||
// Copy block data into FigureData
|
||||
//memcpy(FigureData.blockdata[BlockIndex], &res.buf[4], FIGURE_BLOCK_SIZE);
|
||||
*/
|
||||
}
|
||||
|
||||
// Some verifications should happen. Like if dataError is set.
|
||||
|
||||
return FigureData; // Return the complete figure data
|
||||
return TempFigureData; // Return the complete figure data
|
||||
}
|
||||
|
||||
|
|
|
@ -72,15 +72,11 @@ void FPortalStatusChecker::CheckPortalStatus()
|
|||
switch (CurrentStatusData.StatusArray[i])
|
||||
{
|
||||
case EFigureStatus::NOT_PRESENT:
|
||||
|
||||
break;
|
||||
case EFigureStatus::PRESENT:
|
||||
//FigureData = ReadFigureBlocks(i);
|
||||
//subref->OnSkylanderAdded.Broadcast(GetFigureID(FigureData), i);
|
||||
break;
|
||||
case EFigureStatus::ADDED:
|
||||
figData = PortalHandleRef->ReadFigureBlocks(i);
|
||||
subref->OnSkylanderAdded.Broadcast(figData.GetFigureID(), i);
|
||||
//figData = PortalHandleRef->ReadFigureBlocks(i);
|
||||
subref->OnSkylanderAdded.Broadcast(00, i);
|
||||
break;
|
||||
case EFigureStatus::REMOVED:
|
||||
subref->OnSkylanderRemoved.Broadcast(00, i);
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
#include "SkyPortalSubsystem.h"
|
||||
#include "Engine/Engine.h"
|
||||
#include "SkyPortal.h"
|
||||
|
||||
#include "HAL/RunnableThread.h"
|
||||
#include "Misc/ScopeLock.h"
|
||||
#include "SkyPortalFigure.h"
|
||||
|
||||
|
||||
void USkyPortalSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
||||
|
@ -213,7 +212,7 @@ void USkyPortalSubsystem::Sleep(int sleepMs) {
|
|||
bool USkyPortalSubsystem::PortalConnect()
|
||||
{
|
||||
PortalHandle = NewObject<USkyPortalIO>();
|
||||
if (IsValid(PortalHandle)) {
|
||||
if (IsValid(PortalHandle) && PortalHandle->bPortalReady) {
|
||||
UE_LOG(LogSkyportalIO, Log, TEXT("Portal connected: "));
|
||||
PortalReady();
|
||||
PortalActivate(1);
|
||||
|
@ -234,7 +233,22 @@ bool USkyPortalSubsystem::IsPortalReady()
|
|||
return false;
|
||||
}
|
||||
|
||||
SKYPORTAL_API void USkyPortalSubsystem::PortalMusic(const USoundWave* Sound)
|
||||
void USkyPortalSubsystem::PortalMusic(const USoundWave* Sound)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void USkyPortalSubsystem::PortalAnalyze(const uint8 index)
|
||||
{
|
||||
FigureArray[index] = PortalHandle->ReadFigureBlocks(index);
|
||||
UE_LOG(LogSkyportalIO, Log, TEXT("Reading figure..."));
|
||||
UE_LOG(LogSkyportalIO, Log, TEXT("decrypted Figure ID : %d"), FigureArray[index].GetFigureID());
|
||||
}
|
||||
|
||||
void USkyPortalSubsystem::GetFigureArray() {
|
||||
FigureArray;
|
||||
for (int i = 0; 16; i++) {
|
||||
FigureArray[i] = PortalHandle->ReadFigureBlocks(i);
|
||||
}
|
||||
return;
|
||||
}
|
|
@ -12,10 +12,11 @@ static const uint8 HASH_CONST[] = {
|
|||
#define FIGURE_TOTAL_BLOCKS 64
|
||||
#define FIGURE_BLOCK_SIZE 16
|
||||
|
||||
/*
|
||||
typedef struct {
|
||||
unsigned char blockdata[FIGURE_TOTAL_BLOCKS][FIGURE_BLOCK_SIZE]; bool error;
|
||||
} FigureDataBlock;
|
||||
|
||||
*/
|
||||
|
||||
|
||||
class FigureData {
|
||||
|
@ -38,8 +39,8 @@ public:
|
|||
uint64 FullToyCodeNumber;
|
||||
FString ToyCode;
|
||||
#pragma endregion
|
||||
int16 ID;
|
||||
int16 VariantID;
|
||||
int16 ID; //Skylander ID
|
||||
int16 VariantID; //Skylander Variant ID
|
||||
#pragma region counters
|
||||
uint8 counter1;
|
||||
uint8 couter2;
|
||||
|
@ -53,10 +54,7 @@ public:
|
|||
|
||||
// Methods
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, meta = (Category = "SkyPortal|Figure"))
|
||||
uint32 GetFigureID();
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, meta = (Category = "SkyPortal|Figure"))
|
||||
uint32 GetFigureIdByIndex(uint32 index);
|
||||
|
||||
//UFUNCTION()
|
||||
|
|
|
@ -1,14 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include "Subsystems/EngineSubsystem.h"
|
||||
#include "SkyPortalRunner.h"
|
||||
#include "CoreMinimal.h"
|
||||
#include "SkyPortalFigure.h"
|
||||
#include "SkyPortalIO.h"
|
||||
#include "SkyPortalRunner.h"
|
||||
#include "Subsystems/EngineSubsystem.h"
|
||||
#include "Delegates/DelegateCombinations.h"
|
||||
#include <Containers/Array.h>
|
||||
|
||||
#include "SkyPortalSubsystem.generated.h"
|
||||
|
||||
|
||||
#pragma region Definitions
|
||||
|
||||
//// Delegates
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnSkylanderAddedDelegate, int32, SkylanderID, int32, Index);
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnSkylanderRemovedDelegate, int32, SkylanderID, int32, Index);
|
||||
|
||||
#pragma endregion
|
||||
|
@ -74,6 +81,12 @@ public:
|
|||
UFUNCTION(BlueprintCallable, meta = (Category = "SkyPortal|NOT FUNCTIONING"))
|
||||
SKYPORTAL_API void PortalMusic(const USoundWave* Sound);
|
||||
|
||||
UFUNCTION(BlueprintCallable, meta = (Category = "SkyPortal|Figure|Debug"))
|
||||
SKYPORTAL_API void PortalAnalyze(const uint8 index);
|
||||
|
||||
UFUNCTION(BlueprintCallable, meta = (Category = "SkyPortal|Commands|Figure"))
|
||||
SKYPORTAL_API void GetFigureArray();
|
||||
|
||||
/**/
|
||||
UFUNCTION(BlueprintCallable, CallInEditor, meta = (Category = "SkyPortal|Commands"))
|
||||
SKYPORTAL_API FPortalStatusData PortalStatus();
|
||||
|
@ -104,6 +117,8 @@ public:
|
|||
UPROPERTY(BlueprintReadOnly)
|
||||
FPortalStatusData StatusData;
|
||||
|
||||
TArray<FigureData> FigureArray;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
float RunnerInterval = 0.01f; //In seconds
|
||||
|
||||
|
|
|
@ -62,9 +62,10 @@ public class SkyPortal : ModuleRules
|
|||
{
|
||||
"Core",
|
||||
"CoreUObject",
|
||||
"Engine"
|
||||
// ... add other public dependencies that you statically link with here ...
|
||||
}
|
||||
"Engine",
|
||||
"OpenSSL",
|
||||
"SSL"
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
|
@ -75,7 +76,7 @@ public class SkyPortal : ModuleRules
|
|||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
// ... add private dependencies that you statically link with here ...
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in a new issue