OpenSSL implementation

This commit is contained in:
Lucas 2024-09-27 01:39:33 +02:00
parent df5fd8b05b
commit f1988072a4
8 changed files with 74 additions and 119 deletions

View file

@ -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

View file

@ -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()
{
}

View file

@ -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
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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()

View file

@ -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

View file

@ -62,8 +62,9 @@ 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 ...
}
);