Subversion Repositories decoder

Compare Revisions

Regard whitespace Rev 26 → Rev 27

/trunk/Decoder5/DecoderMain.pas
107,8 → 107,62
type
TDcFormatVersion = (fvUnknown, fvDc40, fvDc41Beta, fvDc41FinalCancelled, fvDc50Wip);
 
TKdfVersion = (kvUnknown, kvKdf1, kvKdf2, kvKdf3, kvKdfx, kvPbkdf2);
 
TDC4FileInfo = record
Dc4FormatVersion: TDcFormatVersion;
IsZLibCompressed: boolean;
IsCompressedFolder: boolean;
OrigFileName: string;
KDF: TKdfVersion;
KDF_Iterations: Integer;
IVSize: integer;
SeedSize: integer;
HashClass: TDECHashClass;
CipherClass: TDECCipherClass;
CipherMode: TCipherMode;
FillMode: TBlockFillMode;
end;
 
const
DC4_ID_BASES: array[0..4] of Int64 = (
DC4_SUBFORMAT_VERSION: array[Low(TDcFormatVersion)..High(TDcFormatVersion)] of string = (
'Unknown',
'(De)Coder 4.0',
'(De)Coder 4.1 Beta',
'(De)Coder 4.1 Final (Cancelled)',
'(De)Coder 5.0 WIP'
);
 
INTEGRITY_CHECK_INFO: array[Low(TDcFormatVersion)..High(TDcFormatVersion)] of string = (
'Unknown', // CalcMac for Hagen Reddmann Example
'Hash of source data',
'Nested Hash of source data with password',
'Nested Hash of source data with password',
'Encrypt-then-HMAC'
);
 
KDF_VERSION_NAMES: array[Low(TKdfVersion)..High(TKdfVersion)] of string = (
'Unknown', 'KDF1', 'KDF2', 'KDF3', 'KDFx', 'PBKDF2'
);
 
CIPHER_MODE_NAMES: array[Low(TCipherMode)..High(TCipherMode)] of string = (
'CTSx = double CBC, with CFS8 padding of truncated final block',
'CBCx = Cipher Block Chaining, with CFB8 padding of truncated final block',
'CFB8 = 8bit Cipher Feedback mode',
'CFBx = CFB on Blocksize of Cipher',
'OFB8 = 8bit Output Feedback mode',
'OFBx = OFB on Blocksize bytes',
'CFS8 = 8Bit CFS, double CFB',
'CFSx = CFS on Blocksize bytes',
'ECBx = Electronic Code Book',
'GCM = Galois Counter Mode'
);
 
CIPHER_FILLMODE_NAMES: array[Low(TBlockFillMode)..High(TBlockFillMode)] of string = (
'Bytes'
);
 
DC4_ID_BASES: array[Low(TDcFormatVersion)..High(TDcFormatVersion)] of Int64 = (
$84485225, // Hagen Reddmann Example (no .dc4 files)
$59178954, // (De)Coder 4.0 (identities not used)
$84671842, // (De)Coder 4.1 beta
176,24 → 230,6
end;
end;
 
type
TKdfVersion = (kvUnknown, kvKdf1, kvKdf2, kvKdf3, kvKdfx, kvPbkdf2);
 
TDC4FileInfo = record
Dc4FormatVersion: TDcFormatVersion;
IsZLibCompressed: boolean;
IsCompressedFolder: boolean;
OrigFileName: string;
KDF: TKdfVersion;
KDF_Iterations: Integer;
IVSize: integer;
SeedSize: integer;
HashClass: TDECHashClass;
CipherClass: TDECCipherClass;
CipherMode: TCipherMode;
FillMode: TBlockFillMode;
end;
 
function DeCoder4X_DecodeFile(const AFileName, AOutput: String; const APassword: RawByteString; const OnlyReadFileInfo: boolean=false): TDC4FileInfo;
var
Source: TStream;
368,7 → 404,7
 
// 4. IdBase (only version 2+)
if V = fvDc40 then
idBase := DC4_ID_BASES[Ord(V)]
idBase := DC4_ID_BASES[V]
else
idBase := ReadLong;
 
724,7 → 760,7
WriteRaw(OrigName);
 
// 4. IdBase (only version 2+)
idBase := DC4_ID_BASES[Ord(fvDc50Wip)];
idBase := DC4_ID_BASES[fvDc50Wip];
WriteLong(idBase);
 
// 5. Cipher identity (only version 2+)
747,6 → 783,7
WriteRaw(Convert(IV));
 
// 7.6 Cipher block filling mode (only version 4+)
Cipher.FillMode := TBlockFillMode.fmByte;
WriteByte(Ord(Cipher.FillMode));
 
// 7.7 Last-Block-Filler (only version 4+)
807,8 → 844,11
end;
end;
 
function YesNo(b: boolean): string;
begin
if b then exit('Yes') else exit('No');
end;
 
 
procedure TFormMain.Button1Click(Sender: TObject);
var
fi: TDC4FileInfo;
832,6 → 872,28
fi := DeCoder4X_DecodeFile('schloss.dc5', '', '', true);
ShowMessage('ok');
 
Memo1.Lines.Clear;
 
Memo1.Lines.Add('File Format: (De)Coder 4.x/5.x Encrypted File');
Memo1.Lines.Add('Sub-Format: ' + IntToStr(Ord(fi.Dc4FormatVersion)) + ' = ' + DC4_SUBFORMAT_VERSION[fi.Dc4FormatVersion]);
Memo1.Lines.Add('Is compressed folder: ' + YesNo(fi.IsCompressedFolder));
Memo1.Lines.Add('Data additionally ZLib-compressed: ' + YesNo(fi.IsZLibCompressed));
Memo1.Lines.Add('Original filename: ' + fi.OrigFileName);
Memo1.Lines.Add('Key Derivation Algorithm: ' + KDF_VERSION_NAMES[fi.KDF]);
if fi.KDF = kvPbkdf2 then
Memo1.Lines.Add('PBKDF Iterations: ' + IntToStr(fi.KDF_Iterations));
Memo1.Lines.Add('Hashing Algorithm: ' + StringReplace(fi.HashClass.ClassName, 'THash_', '', []));
Memo1.Lines.Add('Hash Digest Size: ' + IntToStr(fi.HashClass.DigestSize));
Memo1.Lines.Add('Hash Block Size: ' + IntToStr(fi.HashClass.BlockSize));
Memo1.Lines.Add('Hash Seed Size: ' + IntToStr(fi.SeedSize));
Memo1.Lines.Add('Encryption Algorithm: ' + StringReplace(fi.CipherClass.ClassName, 'TCipher_', '', []));
Memo1.Lines.Add('Cipher Key Size: ' + IntToStr(fi.CipherClass.Context.KeySize));
Memo1.Lines.Add('Cipher Block Size: ' + IntToStr(fi.CipherClass.Context.BlockSize));
Memo1.Lines.Add('Cipher Buffer Size: ' + IntToStr(fi.CipherClass.Context.BufferSize));
Memo1.Lines.Add('Cipher IV Size: ' + IntToStr(fi.IVSize));
Memo1.Lines.Add('Cipher Mode: ' + CIPHER_MODE_NAMES[fi.CipherMode]);
Memo1.Lines.Add('Cipher Block Filling Mode: ' + CIPHER_FILLMODE_NAMES[fi.FillMode]);
Memo1.Lines.Add('Message Authentication: ' + INTEGRITY_CHECK_INFO[fi.Dc4FormatVersion]);
end;
 
{ TDECHashExtendedAuthentication }
/trunk/Private/dc4-spec.txt
33,7 → 33,7
This file format is NOT used by (De)Coder.
It is only the guideline of the DC4-Format.
Hagen Reddmann posted the demo-algorithm in this topic:
https://www.delphipraxis.net/topic79794,0,asc,0.html (in German)
https://www.delphipraxis.net/66783-sichere-verschluesselung-von-dateien-mit-dem-dec-5-1-a.html (in German)
 
---------------------------------------------------------------------------------------------------
Offset Type Size Content/Description
110,7 → 110,7
Long 4 Size of data
Binary var DEC 5.1c encrypted data; Password = Hash->KDfx(User-Password, Seed); KDFx is proprietary to DEC
Byte 1 Size of CalcMAC
Binary 0-255 CalcMAC; Size depends on cipher algorithm and cipher mode. The algorithms of DEC give out CalcMAC with the length 16-64.
Binary 0-255 DEC "CalcMAC"; Size depends on cipher algorithm and cipher mode. The algorithms of DEC give out CalcMAC with the length 16-64.
---------------------------------------------------------------------------------------------------