Subversion Repositories decoder

Rev

Rev 26 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 26 Rev 27
Line 105... Line 105...
105
  end;
105
  end;
106
 
106
 
107
type
107
type
108
  TDcFormatVersion = (fvUnknown, fvDc40, fvDc41Beta, fvDc41FinalCancelled, fvDc50Wip);
108
  TDcFormatVersion = (fvUnknown, fvDc40, fvDc41Beta, fvDc41FinalCancelled, fvDc50Wip);
109
 
109
 
-
 
110
  TKdfVersion = (kvUnknown, kvKdf1, kvKdf2, kvKdf3, kvKdfx, kvPbkdf2);
-
 
111
 
-
 
112
  TDC4FileInfo = record
-
 
113
    Dc4FormatVersion: TDcFormatVersion;
-
 
114
    IsZLibCompressed: boolean;
-
 
115
    IsCompressedFolder: boolean;
-
 
116
    OrigFileName: string;
-
 
117
    KDF: TKdfVersion;
-
 
118
    KDF_Iterations: Integer;
-
 
119
    IVSize: integer;
-
 
120
    SeedSize: integer;
-
 
121
    HashClass: TDECHashClass;
-
 
122
    CipherClass: TDECCipherClass;
-
 
123
    CipherMode: TCipherMode;
-
 
124
    FillMode: TBlockFillMode;
-
 
125
  end;
-
 
126
 
110
const
127
const
-
 
128
  DC4_SUBFORMAT_VERSION: array[Low(TDcFormatVersion)..High(TDcFormatVersion)] of string = (
-
 
129
    'Unknown',
-
 
130
    '(De)Coder 4.0',
-
 
131
    '(De)Coder 4.1 Beta',
-
 
132
    '(De)Coder 4.1 Final (Cancelled)',
-
 
133
    '(De)Coder 5.0 WIP'
-
 
134
  );
-
 
135
 
-
 
136
  INTEGRITY_CHECK_INFO: array[Low(TDcFormatVersion)..High(TDcFormatVersion)] of string = (
-
 
137
    'Unknown', // CalcMac for Hagen Reddmann Example
-
 
138
    'Hash of source data',
-
 
139
    'Nested Hash of source data with password',
-
 
140
    'Nested Hash of source data with password',
-
 
141
    'Encrypt-then-HMAC'
-
 
142
  );
-
 
143
 
-
 
144
  KDF_VERSION_NAMES: array[Low(TKdfVersion)..High(TKdfVersion)] of string = (
-
 
145
    'Unknown', 'KDF1', 'KDF2', 'KDF3', 'KDFx', 'PBKDF2'
-
 
146
  );
-
 
147
 
-
 
148
  CIPHER_MODE_NAMES: array[Low(TCipherMode)..High(TCipherMode)] of string = (
-
 
149
    'CTSx = double CBC, with CFS8 padding of truncated final block',
-
 
150
    'CBCx = Cipher Block Chaining, with CFB8 padding of truncated final block',
-
 
151
    'CFB8 = 8bit Cipher Feedback mode',
-
 
152
    'CFBx = CFB on Blocksize of Cipher',
-
 
153
    'OFB8 = 8bit Output Feedback mode',
-
 
154
    'OFBx = OFB on Blocksize bytes',
-
 
155
    'CFS8 = 8Bit CFS, double CFB',
-
 
156
    'CFSx = CFS on Blocksize bytes',
-
 
157
    'ECBx = Electronic Code Book',
-
 
158
    'GCM  = Galois Counter Mode'
-
 
159
  );
-
 
160
 
-
 
161
  CIPHER_FILLMODE_NAMES: array[Low(TBlockFillMode)..High(TBlockFillMode)] of string = (
-
 
162
    'Bytes'
-
 
163
  );
-
 
164
 
111
  DC4_ID_BASES: array[0..4] of Int64 = (
165
  DC4_ID_BASES: array[Low(TDcFormatVersion)..High(TDcFormatVersion)] of Int64 = (
112
    $84485225, // Hagen Reddmann Example (no .dc4 files)
166
    $84485225, // Hagen Reddmann Example (no .dc4 files)
113
    $59178954, // (De)Coder 4.0 (identities not used)
167
    $59178954, // (De)Coder 4.0 (identities not used)
114
    $84671842, // (De)Coder 4.1 beta
168
    $84671842, // (De)Coder 4.1 beta
115
    $19387612, // (De)Coder 4.1 final/cancelled
169
    $19387612, // (De)Coder 4.1 final/cancelled
116
    $1259d82a  // (De)Coder 5.0 WIP
170
    $1259d82a  // (De)Coder 5.0 WIP
Line 174... Line 228...
174
  finally
228
  finally
175
    FreeAndNil(CompressInputStream);
229
    FreeAndNil(CompressInputStream);
176
  end;
230
  end;
177
end;
231
end;
178
 
232
 
179
type
-
 
180
  TKdfVersion = (kvUnknown, kvKdf1, kvKdf2, kvKdf3, kvKdfx, kvPbkdf2);
-
 
181
 
-
 
182
  TDC4FileInfo = record
-
 
183
    Dc4FormatVersion: TDcFormatVersion;
-
 
184
    IsZLibCompressed: boolean;
-
 
185
    IsCompressedFolder: boolean;
-
 
186
    OrigFileName: string;
-
 
187
    KDF: TKdfVersion;
-
 
188
    KDF_Iterations: Integer;
-
 
189
    IVSize: integer;
-
 
190
    SeedSize: integer;
-
 
191
    HashClass: TDECHashClass;
-
 
192
    CipherClass: TDECCipherClass;
-
 
193
    CipherMode: TCipherMode;
-
 
194
    FillMode: TBlockFillMode;
-
 
195
  end;
-
 
196
 
-
 
197
function DeCoder4X_DecodeFile(const AFileName, AOutput: String; const APassword: RawByteString; const OnlyReadFileInfo: boolean=false): TDC4FileInfo;
233
function DeCoder4X_DecodeFile(const AFileName, AOutput: String; const APassword: RawByteString; const OnlyReadFileInfo: boolean=false): TDC4FileInfo;
198
var
234
var
199
  Source: TStream;
235
  Source: TStream;
200
 
236
 
201
  procedure Read(var Value; Size: Integer);
237
  procedure Read(var Value; Size: Integer);
Line 366... Line 402...
366
    else
402
    else
367
      Assert(False);
403
      Assert(False);
368
 
404
 
369
    // 4. IdBase (only version 2+)
405
    // 4. IdBase (only version 2+)
370
    if V = fvDc40 then
406
    if V = fvDc40 then
371
      idBase := DC4_ID_BASES[Ord(V)]
407
      idBase := DC4_ID_BASES[V]
372
    else
408
    else
373
      idBase := ReadLong;
409
      idBase := ReadLong;
374
 
410
 
375
    // 5. Cipher identity (only version 2+)
411
    // 5. Cipher identity (only version 2+)
376
    if V = fvDc40 then
412
    if V = fvDc40 then
Line 722... Line 758...
722
    OrigName := UTF8Encode(ExtractFileName(AFileName));
758
    OrigName := UTF8Encode(ExtractFileName(AFileName));
723
    WriteByte(Length(OrigName));
759
    WriteByte(Length(OrigName));
724
    WriteRaw(OrigName);
760
    WriteRaw(OrigName);
725
 
761
 
726
    // 4. IdBase (only version 2+)
762
    // 4. IdBase (only version 2+)
727
    idBase := DC4_ID_BASES[Ord(fvDc50Wip)];
763
    idBase := DC4_ID_BASES[fvDc50Wip];
728
    WriteLong(idBase);
764
    WriteLong(idBase);
729
 
765
 
730
    // 5. Cipher identity (only version 2+)
766
    // 5. Cipher identity (only version 2+)
731
    CipherClass := TCipher_AES;
767
    CipherClass := TCipher_AES;
732
    WriteLong(DEC51_Identity(idBase, CipherClass.ClassName));
768
    WriteLong(DEC51_Identity(idBase, CipherClass.ClassName));
Line 745... Line 781...
745
    WriteByte(16);
781
    WriteByte(16);
746
    IV := RandomBytes(16);
782
    IV := RandomBytes(16);
747
    WriteRaw(Convert(IV));
783
    WriteRaw(Convert(IV));
748
 
784
 
749
    // 7.6 Cipher block filling mode (only version 4+)
785
    // 7.6 Cipher block filling mode (only version 4+)
-
 
786
    Cipher.FillMode := TBlockFillMode.fmByte;
750
    WriteByte(Ord(Cipher.FillMode));
787
    WriteByte(Ord(Cipher.FillMode));
751
 
788
 
752
    // 7.7 Last-Block-Filler (only version 4+)
789
    // 7.7 Last-Block-Filler (only version 4+)
753
    Filler := $FF;
790
    Filler := $FF;
754
    WriteByte(Filler);
791
    WriteByte(Filler);
Line 805... Line 842...
805
      SecureDeleteFile(ATempFileName);
842
      SecureDeleteFile(ATempFileName);
806
    end;
843
    end;
807
  end;
844
  end;
808
end;
845
end;
809
 
846
 
-
 
847
function YesNo(b: boolean): string;
-
 
848
begin
-
 
849
  if b then exit('Yes') else exit('No');
810
 
850
end;
811
 
851
 
812
procedure TFormMain.Button1Click(Sender: TObject);
852
procedure TFormMain.Button1Click(Sender: TObject);
813
var
853
var
814
  fi: TDC4FileInfo;
854
  fi: TDC4FileInfo;
815
begin
855
begin
Line 830... Line 870...
830
  ShowMessage('ok');
870
  ShowMessage('ok');
831
 
871
 
832
  fi := DeCoder4X_DecodeFile('schloss.dc5', '', '', true);
872
  fi := DeCoder4X_DecodeFile('schloss.dc5', '', '', true);
833
  ShowMessage('ok');
873
  ShowMessage('ok');
834
 
874
 
-
 
875
  Memo1.Lines.Clear;
-
 
876
 
-
 
877
  Memo1.Lines.Add('File Format: (De)Coder 4.x/5.x Encrypted File');
-
 
878
  Memo1.Lines.Add('Sub-Format: ' + IntToStr(Ord(fi.Dc4FormatVersion)) + ' = ' + DC4_SUBFORMAT_VERSION[fi.Dc4FormatVersion]);
-
 
879
  Memo1.Lines.Add('Is compressed folder: ' + YesNo(fi.IsCompressedFolder));
-
 
880
  Memo1.Lines.Add('Data additionally ZLib-compressed: ' + YesNo(fi.IsZLibCompressed));
-
 
881
  Memo1.Lines.Add('Original filename: ' + fi.OrigFileName);
-
 
882
  Memo1.Lines.Add('Key Derivation Algorithm: ' + KDF_VERSION_NAMES[fi.KDF]);
-
 
883
  if fi.KDF = kvPbkdf2 then
-
 
884
    Memo1.Lines.Add('PBKDF Iterations: ' + IntToStr(fi.KDF_Iterations));
-
 
885
  Memo1.Lines.Add('Hashing Algorithm: ' + StringReplace(fi.HashClass.ClassName, 'THash_', '', []));
-
 
886
  Memo1.Lines.Add('Hash Digest Size: ' + IntToStr(fi.HashClass.DigestSize));
-
 
887
  Memo1.Lines.Add('Hash Block Size: ' + IntToStr(fi.HashClass.BlockSize));
-
 
888
  Memo1.Lines.Add('Hash Seed Size: ' + IntToStr(fi.SeedSize));
-
 
889
  Memo1.Lines.Add('Encryption Algorithm: ' + StringReplace(fi.CipherClass.ClassName, 'TCipher_', '', []));
-
 
890
  Memo1.Lines.Add('Cipher Key Size: ' + IntToStr(fi.CipherClass.Context.KeySize));
-
 
891
  Memo1.Lines.Add('Cipher Block Size: ' + IntToStr(fi.CipherClass.Context.BlockSize));
-
 
892
  Memo1.Lines.Add('Cipher Buffer Size: ' + IntToStr(fi.CipherClass.Context.BufferSize));
-
 
893
  Memo1.Lines.Add('Cipher IV Size: ' + IntToStr(fi.IVSize));
-
 
894
  Memo1.Lines.Add('Cipher Mode: ' + CIPHER_MODE_NAMES[fi.CipherMode]);
-
 
895
  Memo1.Lines.Add('Cipher Block Filling Mode: ' + CIPHER_FILLMODE_NAMES[fi.FillMode]);
-
 
896
  Memo1.Lines.Add('Message Authentication: ' + INTEGRITY_CHECK_INFO[fi.Dc4FormatVersion]);
835
end;
897
end;
836
 
898
 
837
{ TDECHashExtendedAuthentication }
899
{ TDECHashExtendedAuthentication }
838
 
900
 
839
class function TDECHashExtendedAuthentication.HMACFile(const Key: TBytes;
901
class function TDECHashExtendedAuthentication.HMACFile(const Key: TBytes;