I got the task to encrypt a firmware file that is decrypted on a small device using AES. The firmware library comes with an AES framework so I need to get that one in sync with my Delphi code....
To get the task done I used the DEC cipher suite which we also use for different purposes in the software... now the thing is that I cannot sync the output of the firmware toolset with DEC...
Here is the code I use:
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
DECBaseClass,
DECCipherBase,
DECHash,
DECCiphers,
DECTypes,
DECFormatBase,
DECFormat;
type
Binary = RawByteString;
var
ACipherClass: TDECCipherClass = TCipher_AES;
ACipherMode: TCipherMode = cmCBCx;
ATextFormat: TDECFormatClass = TFormat_Mime64;
InvertUINT32 : boolean = False;
InvertText : boolean = False;
type
//TMK6AESTextSize = Array[0..15] of UInt32;
TMK6AESTextSize = Array[0..3] of UInt32;
TMK6Key = Array[0..3] of UINT32;
const mk6Key : TMK6Key = ($1, $0, $0, $0);
//mk6Key : TMK6Key = ($09CF4F3C, $ABF71588, $28AED2A6, $2B7E1516 ); // rotated
//mk6IV : TMK6Key = ($00010203 , $04050607 , $08090A0B , $0C0D0E0F);
mk6IV : TMK6Key = ($0 , $0 , $0 , $0);
//mk6IV : TMK6Key = ($0C0D0E0F, $08090A0B, $04050607, $00010203);
// mk6Plaintext : TMK6AESTextSize =
// ( $E2BEC16B ,$969F402E ,$117E3DE9 ,$2A179373 ,
// $578A2DAE ,$9CAC031E ,$AC6FB79E ,$518EAF45 ,
// $461CC830 ,$11E45CA3 ,$19C1FBE5 ,$EF520A1A ,
// $45249FF6 ,$179B4FDF ,$7B412BAD ,$10376CE6 );
// mk6Plaintext : TMK6AESTextSize =
// ( $E2BEC16B ,$969F402E ,$117E3DE9 ,$2A179373 );
//mk6Plaintext : TMK6AESTextSize =
// ( $2A179373, $117E3DE9, $969F402E, $E2BEC16B );
mk6Plaintext : TMK6AESTextSize = ( $0, $0, $0, $0 );
type
TUINT32Byte = Array[0..3] of Byte;
PUINT32Byte = ^TUINT32Byte;
function InvUINT32( value : UINT32 ) : UINT32;
var v1, v2 : PUINT32Byte;
begin
v1 := @value;
v2 := @Result;
v2^[3] := v1^[0];
v2^[2] := v1^[1];
v2^[1] := v1^[2];
v2^[0] := v1^[3];
end;
function GenMK6Text( const txt : TMK6AESTextSize ) : TMK6AESTextSize;
var i : integer;
begin
if InvertText then
begin
for i := 0 to High(txt) do
Result[i] := InvUINT32(txt[i]);
end
else
Result := txt;
end;
function GenMK6Key( const aKey : TMK6Key ) : TMK6Key;
var i : integer;
begin
Result := aKey;
if InvertUINT32 then
begin
for i := 0 to High(aKey) do
Result[i] := InvUINT32(aKey[i]);
end;
end;
function EncryptBin(const buf : TMK6AESTextSize): Binary;
var AData: Binary;
cipher : TCipher_AES128; //AES
aKey : TMK6Key;
aIV : TMK6Key;
aBuf : TMK6AESTextSize;
begin
cipher := TCipher_AES128.Create;
try
cipher.Mode := ACipherMode;
aKey := GenMK6Key(mk6Key);
aIV := GenMK6Key(mk6IV);
aBuf := GenMK6Text(buf);
cipher.Init( aKey, sizeof(mk6key), aIV, sizeof(mk6IV) );
SetLength(AData, sizeof(buf));
cipher.Encode(aBuf, AData[1], Length(AData));
Result := AData;
finally
cipher.Free;
end;
end;
function DecryptBin(buf : Binary): TMK6AESTextSize;
var AData: Binary;
//ACheck: Binary;
//APass: Binary;
ALen: Integer;
ARes : Binary;
cipher : TCipher_AES128;
aKey : TMK6Key;
aIV : TMK6Key;
begin
cipher := TCipher_AES128.Create;
try
//AData := ValidFormat(ATextFormat).Decode(AText);
AData := buf;
ALen := Length(AData); // - cipher.Context.BufferSize;
//ALen := Length(AData); // - cipher.Context.BufferSize;
//ACheck := System.Copy(Adata, ALen 1, cipher.Context.BufferSize);
cipher.Mode := ACipherMode;
aKey := GenMK6Key(mk6Key);
aIV := GenMK6Key(mk6IV);
cipher.Init(aKey, sizeof(mk6key), aIV, sizeof(mk6IV));
SetLength(ARes, ALen);
cipher.Decode(AData[1], ARes[1], ALen);
//if ACheck <> cipher.CalcMAC then
// raise Exception.Create('Invalid data');
Assert(Length(ARes) >= sizeof(Result), 'WTF');
Move(ARes[1], Result, sizeof(Result));
Result := GenMK6Text(Result);
finally
cipher.Free;
end;
end;
var binBuf : Binary;
decBuf : TMK6AESTextSize;
i : integer;
begin
try
binBuf := EncryptBin(mk6Plaintext);
for i := 1 to Length(binBuf) do
begin
Write( IntToHex( Ord(binBuf[i]), 2 ) ' ' );
end;
Writeln;
decBuf := DecryptBin(binBuf);
for i := 0 to Length(decBuf) - 1 do
Writeln( IntToHex( decBuf[i], 4 ) );
readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
The output of the firmware tool is D5 AA 45 05 7C A9 A2 6D 43 D1 63 36 84 1C 3D 2A (which actually also is the output if I use this input on http://aes.online-domain-tools.com/ ) so I guess I miss something here....
Please note that if all input data (Key, IV data) is set to zero I get the output 66 E9 4B D4 EF 8A 2C 3B 88 4C FA 59 CA 34 2B 2E which is close to the one I get from the other tool: D4 4B E9 66 3B 2C 8A EF 59 FA 4C 88 2E 2B 34 CA ... so basically only the UINT32 byte order is different.
The thing is that I cannot get any close if just one bit is different from 0 in the key vector (hence the one value of 1.) ... I tried various things... change the position of the "1", changed the lowest to the highest bit - nothing worked... What am I missing here?
CodePudding user response:
You are using older DEC library that was written to be compatible with Delphi 2009.
Instead of this version you should be using newer DEC library that is fully compatible with with newer Delphi versions including Delphi 11 that you are using.
Switching to newer version of DEC library should solve all of your problems.