Giter Club home page Giter Club logo

delphiencryptioncompendium's Introduction

DEC - Delphi Encryption Compendium

What is DEC?

DEC is a library for Embarcadero Delphi, containing different cryptographic algorithms. It contains algorithms for these categories:

  • Ciphers: encryption/decryption of data
  • Hashes: "cryptographic checksums"
  • Key derivation algorithms like Kdf1-Kdf3 and pbkdf2
  • HMAC message authentication
  • A cryptographic pseudo random number generator
  • CRCs: non cryptographic checksums based on CRC algorithms

Which Delphi versions are compatible?

The current version 6.4.1 is compatible with Delphi 2009 - Delphi 11.0 Alexandria. When defining the NO_ASM define in DECOptions.inc it is compatible with all platforms supported by Delphi! It might be compatible with FPC, but this has not been focus and is not tested. The development branch contains a more FPC compatible version already.

If you need support for older Delphi versions use version 5.2, which is compatible with Delphi 7-2007 at least but lacks some hash implementations, HMAC and KDF improvements. While V5.2 can be made compatible with newer Delphi versions with small modifications we strongly recommend to better adapt your code to use the current version of DEC, given all these improvements made since then. A list of changes is available in the docs folder.

What is the current status of this project?

V6.0 was released shortly before Christmas 2020. Since then work continued by some users supplying code, reporting bugs (regressions) along with fixes and by adding SHA2-224 which was still missing. Details about the changes and additions in V6.4.1 can be found in the VersionHistory.pdf file in the docs subfolder of the development branch.

In comparison to 5.2 we added some console, VCL and FMX based demo applications. The FMX based demos are even available via Google play as "DEC cipher demo" and "DEC hash demo".

Where can I get further information? For example if I'd like to contribute?

In the root folder of DEC V6.4.1 you will find further files with information about this project like NOTICE.txt, CONTRIBUTING.md, SECURITY.md. Also take the time to read DEC64.pdf in the Docs folder and look at the demos provided in the Demos subfolder.

Has it been tested?

DEC 5.2 came with some "arcane" test program testing the algoithms implemented using test data supplied via some text file. For many algorithms this test data stems from official documentation of the algorithms itsself. DEC 5.2 passes these tests.

DEC 6.0 reworked these tests into DUnit and DUnitX tests. We also added some more tests and with this replaced the "arcane" test program which used hard to understand code. A few of the implemented unit tests may still fail, but this is simply because they are empty sceletons at this point in time waiting to be filled in. We first need to work out how to implement these tests and maybe look for test data. Why don't you help out by researching useful test data for those few tests? We're talking at block chaining mode tests for the ciphers specifically.

In DEC 6.2 the unit tests for the hash classes were looked at and where not already used original test data vectors (as far as we could find them - for most we could) have been added to improve test coverage. V6.3 added further synthesized tests for some hash classes. For SHA3 and for the GCM block chaining method the original test vectors provided by NIST are used for the unit tests.

Contained hash algorithms

  • MD2
  • MD4
  • MD5
  • RipeMD128
  • RipeMD160
  • RipeMD256
  • RipeMD320
  • SHA0
  • SHA1
  • SHA224
  • SHA256
  • SHA384
  • SHA512
  • SHA3_224
  • SHA3_256
  • SHA3_384
  • SHA3_512
  • Shake128
  • Shake256
  • Haval128
  • Haval160
  • Haval192
  • Haval224
  • Haval256
  • Tiger
  • Panama
  • Whirlpool0
  • Whirlpool1
  • WhirlpoolT
  • Square
  • Snefru128
  • Snefru256
  • Sapphire

Contained cipher algorithms

  • Null
  • Blowfish
  • Twofish
  • IDEA
  • Cast256
  • Mars
  • RC4
  • RC6
  • AES
  • Square
  • SCOP
  • Sapphire
  • 1DES
  • 2DES
  • 3DES
  • 2DDES
  • 3DDES
  • 3TDES
  • 3Way
  • Cast128
  • Gost
  • Magma
  • Misty
  • NewDES
  • Q128
  • RC2
  • RC5
  • SAFER
  • Shark
  • Skipjack
  • TEA
  • XTEA
  • TEAN

Contained block concatenating modes

Modes ending on x have been invented by the original developer of DEC

  • ECBx
  • CBCx
  • CTSx
  • CTS3
  • CFB8
  • CFBx
  • OFB8
  • OFBx
  • CFS8
  • CFSx
  • GCM

Contained key derivation algorithms:

  • KDF1
  • KDF2
  • KDF3
  • MGF1
  • PBKDF2

Contained message authentication algorithms

  • HMAC

Contained formattings

  • Copy
  • HEX
  • HEXL
  • Base16
  • Base16L
  • DECMIME32
  • Base64
  • MIME64
  • Radix64
  • PGP
  • UU
  • XX
  • ESCAPE
  • BigEndian16
  • BigEndian32
  • BigEndian64

Contained CRCs

  • 8
  • 10
  • 12
  • 16
  • 16CCITT
  • 16XModem
  • 24
  • 32
  • 32CCITT
  • 32ZModem
  • 8ATMHEC
  • 8SMBus
  • 15CAN
  • 16ZMODEM

delphiencryptioncompendium's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

delphiencryptioncompendium's Issues

Add Base32 for use with OTP

I'd like to use DEC for creating One Time Passwords (OTP) such as Google Authenticator, but this requires Base32 encoding support
RFC 4226

3DES DoEncode()/DoDecode() Source overwriting Dest problem

Preface
I'm updating very (very!) old code that used DEC3 by using the latest version available at time of writing.
For backward compatibility reasons I have to make sure (for now) that ciphers encoded/decoded are identical to DEC3, so I enabled compatibility mode (DEC3_CMCTS) for 3-DES and fixed the DecodeCTS3 method which was missing the TDECCipherModes class in the implementation (which is also a minor bug in current DECCipherModes unit).

When I compared the output of the new DEC6 cipher implementation against that of DEC3 I saw they were not identical.

After some investigation I noticed something that strikes me odd in the implementation of the 2DES and 3DES cipher DoEncode and DoDecode methods and after changing it in the library, the results were identical to DEC3 again.

Also, when comparing the implementation of 2DES and 3DES to other DES ciphers (like 2DDES and 3DDES) it appears that both 2DES and 3DES contain the same bug.

Describe the bug
Implementation of 3DES DoEncode- and DoDecode-methods (for 2DES it's similar, but not checked myself):

procedure TCipher_3DES.DoEncode(Source, Dest: Pointer; Size: Integer);
begin
  Assert(Size = Context.BlockSize);
  DES_Func(Source, Dest, @PUInt32Array(FAdditionalBuffer)[ 0]);
  DES_Func(Source, Dest, @PUInt32Array(FAdditionalBuffer)[32]);
  DES_Func(Source, Dest, @PUInt32Array(FAdditionalBuffer)[64]);
end;

procedure TCipher_3DES.DoDecode(Source, Dest: Pointer; Size: Integer);
begin
  Assert(Size = Context.BlockSize);
  DES_Func(Source, Dest, @PUInt32Array(FAdditionalBuffer)[96]);
  DES_Func(Source, Dest, @PUInt32Array(FAdditionalBuffer)[128]);
  DES_Func(Source, Dest, @PUInt32Array(FAdditionalBuffer)[160]);
end;

If I correctly understand the code, the first call to DES_Func will take the Source and put the result in Dest, but the second and third call to DES_Func will also take the original Source and will each overwrite Dest again, resulting in only the last call being effective on the output, resulting in an erroneous result.

Expected and actual behavior
When I change the code to the following, the result is as expected:

procedure TCipher_3DES.DoEncode(Source, Dest: Pointer; Size: Integer);
begin
  Assert(Size = Context.BlockSize);
  DES_Func(Source, Dest, @PUInt32Array(FAdditionalBuffer)[ 0]);
  DES_Func(Dest, Dest, @PUInt32Array(FAdditionalBuffer)[32]);
  DES_Func(Dest, Dest, @PUInt32Array(FAdditionalBuffer)[64]);
end;

procedure TCipher_3DES.DoDecode(Source, Dest: Pointer; Size: Integer);
begin
  Assert(Size = Context.BlockSize);
  DES_Func(Source, Dest, @PUInt32Array(FAdditionalBuffer)[96]);
  DES_Func(Dest, Dest, @PUInt32Array(FAdditionalBuffer)[128]);
  DES_Func(Dest, Dest, @PUInt32Array(FAdditionalBuffer)[160]);
end;

I haven't checked 2DES myself, but the problem appears to be there as well.

TCipher_SCOP out-of-bounds read

DEC's SCOP implementation is broken. I noticed this while porting the older version of the library (the "unofficial fork", as you call it) to PowerPC.

The array indices in these 3 lines all need to be + 1 like the first one, else they read out-of-bounds data when I >= 4. Also refer to the original spec.

On big endian processors the byte order of the following 32-bit array in the struct is different, which is why it was causing different results than on little endian processors. It had me quite confused for a couple hours.

PS: I've seen your issue in my repository and will provide my views on the matter soon-ish.

Question about processing of last block of data using Done

In the examples we can see the following usage of encryption:

      // Encrypt
      Output := Cipher.EncodeBytes(Input);
      // clean up inside the cipher instance, which also removes the key from RAM
      Cipher.Done;

      // Decrypt
      Cipher.Init(RawByteString(StringOf(KeyKDF)), IV, 0);
      Output := Cipher.DecodeBytes(Output);
      // clean up inside the cipher instance, which also removes the key from RAM
      Cipher.Done;

The documentation of TDECCipher.Done says:

    ///   Properly finishes the cryptographic operation. It needs to be called
    ///   at the end of encrypting or decrypting data, otherwise the last block
    ///   or last byte of the data will not be properly processed.

(You probably also want to add the argument "removes the key from RAM" in that documentation)

I am confused about the argument "last block or last byte of data will not be properly processed". The Done method does not return data, so it looks like the "processing of the last block" is useless??

      Cipher.Init(RawByteString(StringOf(KeyKDF)), IV, 0);
      Output := Cipher.DecodeBytes(Output); // <-- output has been received here
      Cipher.Done; // <-- "processing" of the last block does not affect "Output"

So I wonder, am I missing something if I don't receive data from the "processing" of the last block? Thanks for clarification!

application in android32 release mode hangs in splash screen

I use Delphi 10.4.2 and I have Oneplus7 android 11

Steps to reproduce the behavior:
Just add DECCiphers in uses list in an activity, compile it in Android 32bit release mode, default settings:
a) run it without debugging from IDE and it hangs on splash screen.
b) run it with debugging from IDE and it gives error: Project .apk raised exception class Bus Error (10) (see image for stack/memory)
c) playing with Compiling options and rebuild it after each change:
i) Turning off optimization, the problem is solved
ii) If "Debug Information" or "Limited Debug information" is selected again the problem is solved.

In debug mode or in both modes of android64, everything is ok

The "exception class Bus Error" is described in the following link as a problem of the compiler for android32 with packed classes:
https://support.tmssoftware.com/t/exception-class-bus-error-when-saving-file/3623

DEC error

Cipher_FMX program logic wrong ?

Hello,
I was just testing the Cipher_FMX program.

I set the Input format to TFormat_Copy and output to TFormat_Hex

Setup the rest and put 'Hello' into the plain text and press Encrypt. Then press Decrypt and its not correct.

Could be my logic or thinking of course.

In the procedure TFormMain.ButtonDecryptClick(Sender: TObject);

I swapped the following which gets it working.

OutputBuffer := (Cipher as TDECFormattedCipher).DecodeBytes(OutputFormatting.Decode(InputBuffer));

EditPlainText.Text := string(DECUtil.BytesToRawString(InputFormatting.Encode(OutputBuffer)));

// OutputBuffer := (Cipher as TDECFormattedCipher).DecodeBytes(InputFormatting.Decode(InputBuffer));
//
// EditPlainText.Text := string(DECUtil.BytesToRawString(OutputFormatting.Encode(OutputBuffer)));

DEC 6.4 is not compatible to XE2 (and below) anymore

The current release contains a few features not supported in XE2

To Reproduce
Open XE2
try to compile any 32bit project, that uses DEC (I haven't tried to compile 64bit)

Details

  • In DECOptions.inc the compilerswitch {$LEGACYIFEND ON} is not available (was introduced in XE4)
  • In DECCipherModesGCM.pas there are a couple places where a UInt64 variable is used in a for loop, which results in E2032 (For loop control variable must have ordinal type)
    • function TGCM.CalcGaloisHash(AuthenticatedData, Ciphertext : TBytes): T128;
    • procedure TGCM.DecodeGCM(Source, Dest: TBytes; Size: Integer);
    • procedure TGCM.EncodeGCM(Source, Dest: TBytes; Size: Integer);
  • Also in DECCipherModesGCM.pas in the function TGCM.GetStandardAuthenticationTagBitLengths: TStandardBitLengths;
    the assignment of an array to the result gives E2010 (Incompatible types - 'TStandardBitLengths' and 'Set')

Can't execute PBKDF2 key derivation function. Please help

I'm having Abstract error: TDECHashAuthentication is not implemented error when calling PBKDF2 function

aes_key, Password, Salt : TBytes;
...
aes_key := TDECHashAuthentication.PBKDF2( Password, Salt, 100000, 32 );

In the TDECHashAuthentication source code there are no implementation of DigestSize, and the exception raised from here:

class function TDECHash.DigestSize: UInt32;
begin
  // C++ does not support virtual static functions thus the base cannot be
  // marked 'abstract'. This is our workaround:
  raise EDECAbstractError.Create(GetShortClassName);
end;

Please help, how to make working PBKDF2 ?

[help wanted, delphi, question]

Different output form AES 256 PHP and Delphi FMX

I have to encrypt/decrypt a string on AES 256 CBC, and I'm getting a shorter string compared wit PHP.

PHP Example:
https://gist.github.com/ezegg/8d54c98b8fbdce263409eabaf8afabe6

    PHP Output
   DB8BRqb2q6BW/HLQYN2pr2n9DTL1Q8kp2lvZi3rogbxjEasiMbgU4q5/vDav+p0O0KWlfMm
   NekXN+UkbUiB+s/LNf1MF2EgOQEZoivxgp+UJxsuT5vDIMmQXUkuwkyUE+a7hH5FwaDDY8D
   NwW2kowFXeE69AcOMaWnyZ+YplKNEUOzQzLstBxWnJE+aSr0+vQN3knkIIjbT10yfSTV/OQA==
  
  FMX Output.
   DB8BRqb2q6BW/HLQYN2pr2n9DTL1Q8kp2lvZi3rogbxjEasiMbgU4q5/vDav+p0O0KWlfMm
   NekXN+UkbUiB+s/LNf1MF2EgOQEZoivxgp+UJxsuT5vDIMmQXUkuwkyUE+a7hH5FwaDDY8D
   NwW2kowFXeE69AcOMaWnyZ+YplKNEUOzQzLstBxWnJE+aSr0+v9Q21xA==

As you can see, string is "shorter" in Delphi.

here is the test string, Secret key and init vector
SECRET_KEY = "HPo7OLqB4Fkk4E2yGOtwqw8H5fHR9kNx67OR4g4UdlA=";
IV = "p5ldmBPdd/9pjC0bDC/nSg==";

Input String:
{"idServicio":79, "idProducto":209 , "referencia": "40425475190118187271", "montoPago": 9999, "telefono":"1111111111", "horaLocal":"20200401222821"}

Thank you

DES encrypt

Hi,

I need to encrypt some strings that are to be verified after with another application.
The other application is in C# and the send me this piece of source code:

public static string encrypt(string value, string key)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.Mode = CipherMode.CBC;
des.Padding = PaddingMode.PKCS7;
des.Key = ASCIIEncoding.ASCII.GetBytes(key);
des.IV = ASCIIEncoding.ASCII.GetBytes(key);

         ICryptoTransform encryptor = des.CreateEncryptor();

         byte[] messageBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(value);

        byte[] encryptedBytes = encryptor.TransformFinalBlock(messageBytes, 0, messageBytes.Length);

        return Convert.ToBase64String(encryptedBytes);
    }

I'm having trouble to make the encryptation compatible.

Example:
using: encrypt(“1234568”, "c9FC57w3");

I should have: bVRN+cnpPLvpJkRE+W5+JQ==

Can you help?

Thank you

Urgent: Migration from DEC 5.2 library. Help wanted

I am trying to migrate from the DEC 5.2 version to the current one for Linux. I have written my own wrapper for the old version of the library and I use this wrapper in my projects. But I see very many changes in the new DEC, I have dozens of compilation errors.
Please help me how to approach this migration.

uses DecUtil, DECCipher, DECHash, DECFmt;

var
ACipherClass: TDECCipherClass = TCipher_Rijndael;
ACipherMode: TCipherMode = cmCBCx;
AHashClass: TDECHashClass = THash_Whirlpool;
ATextFormat: TDECFormatClass = TFormat_Mime64;
AKDFIndex: LongWord = 1;

function Encrypt(const AText: WideString; const APassword: WideString): WideString;
var
ASalt: Binary;
AData: Binary;
APass: Binary;
begin
with ValidCipher(ACipherClass).Create, Context do
try
ASalt := .... ;
APass := ValidHash(AHashClass).KDFx(APassword[1], System.Length(APassword) * SizeOf(APassword[1]), ASalt[1], System.Length(ASalt), KeySize, TFormat_Copy, AKDFIndex);
Mode := ACipherMode;
Init(APass);
SetLength(AData, System.Length(AText) * SizeOf(AText[1]));
Encode(AText[1], AData[1], System.Length(AData));
Result := ValidFormat(ATextFormat).Encode(ASalt + AData + CalcMAC);
finally
Free;
end;
end;

Haval hashes Rounds value is reset by Init call; Whirlpool rev2 missing; Tiger hash name

##1. Currently Haval hashes have "hardcoded" rounds value:
· THash_Haval128 = 128/3
· THash_Haval160 = 160/3
· THash_Haval192 = 192/4
· THash_Haval224 = 224/4
· THash_Haval256 = 256/5
~~ Would be helpful to allow to set Rounds value in constructor.


##2. Problem currently is that FCount (rounds) value is reset to "0" in 
"TDECHash.Init;" - called in CalcBuffer (CalcBinary), so even user created an 
object:

  Haval := THash_Haval256.Create;
  Haval.Rounds := 4;
  Haval.CalcBinary(Str, DECFmt.TFormat_HEXL);
  Haval.Free;

= would have no effect, because .SetRounds is called twice - 1st to "4", then 
2nd time by Init resets to "0", which will then results in default "5" value 
for 256 digest..


##3. Some of Hash functions have counterintuitive names:
· THash_Whirlpool  = is actually Whirlpool-0
· THash_Whirlpool1 = Whirlpool-T
· And Whirlpool/Whirlpool-2 = not implemented..

##4. Implemented "THash_Tiger" has is actually:
· Tiger (192/3)
~~ Would be helpful to change name / implement / allow to set Digest and 
Rounds..

For example:
· Tiger (128/3),  · Tiger (160/3),  · Tiger (192/3)
· Tiger (128/4),  · Tiger (160/4),  · Tiger (192/4)


##5. Would be useful to add "SHA-2 (224)" Hash


------------------------------------------------
## Current Haval workaround - manually calling all "Init, manual set, Calc" 
code:

program Project1;
{$AppType Console}
uses
  DECHash,
  DECFmt;

function Haval_Str(Str: string; DS: Integer; Rounds: Byte = 5): string;
var
  Haval: THashBaseHaval;
begin
  Result := '';

  case DS of
    128: Haval := THash_Haval128.Create;
    160: Haval := THash_Haval160.Create;
    192: Haval := THash_Haval192.Create;
    224: Haval := THash_Haval224.Create;
    256: Haval := THash_Haval256.Create;
  end;

  try
    Haval.Init; //Called by CalcBinary/CalcBuffer == Resets any customizations made..
    Haval.Rounds := Rounds; //override value.
    Haval.Calc(Str[1], Length(Str));
    Haval.Done;
    Result := Haval.DigestStr(DECFmt.TFormat_HEXL);
  finally
    Haval.Free;
  end;
end;

var
  d, r: Integer;
begin
  for r := 3 to 5 do
  begin
    d := 128;
    repeat
      Writeln( 'haval (', d, '/', r, '): ', Haval_Str('test', d, r) );
      inc(d, 32);
    until (d > 256);
    Writeln;
  end;
  Readln;
end.
------------------------------------------------

Original issue reported on code.google.com by [email protected] on 14 Nov 2012 at 5:20

Unit 'DECCipherBase' not found

I have just installed the library via Getit Package Manager on Delphi 10.3 Version 26.0.36039.7899
Restarted IDE
But able compile nothing:

[dcc32 Fatal Error] test.pas(8): F2613 Unit 'DECCipherBase' not found.

Could you help, what should I do to next? Thanks

TCipher_2DES encrypts as single-DES

What steps will reproduce the problem?
1. Create a TChiper_2DES object
2. Encrypt using double-length key (16 bytes)
3. Compare to results using doubled single-length key with same first half as 
in #2

What is the expected output? What do you see instead?
Results from #3 should be different than results from #2, but are always the 
same, equivalent to single DES.

What version of the product are you using? On what operating system?
Version 5.2, Win 7 64-bit, Delphi 2010 Version 14.0.3593.25826 

Please provide any additional information below.
Strangely, decrypt works correctly. Use 
http://people.eku.edu/styere/Encrypt/JS-DES.html to test, as it does both 
single and triple DES.

Original issue reported on code.google.com by [email protected] on 17 Aug 2012 at 3:09

DECCipherInterface error

I have a project group that uses the DEC code base to replace some older DCrypt units.

There are two projects sharing the same code: one is compiled as a console EXE that runs a web server under localhost, the other is an ISAPI dll. So apart from the DPR file the code base is the same.

I can compile the EXE, but the DLL compilation fails with this error

[dcc64 Error] DECCipherInterface.pas(746): E2134 Type '<void>' has no type info

Commenting out the line at 486 in this unit
procedure Init(const Key; Size: Integer; const IVector; IVectorSize: Integer; IFiller: Byte = $FF); overload;
allows compilation to succeed.

This method declaration contains an untyped parameter. Is this causing the failure ?
And if so why does it compile under the EXE but not the DLL?

Incorrect auth tag generated for GCM mode when feeding data using small chunks

Describe the bug
Incorrect auth tag generated for GCM mode when feeding data using small chunks (at least when sized to cipher's block size). Using such small chunks appear to conform with DEC's documentation.

To Reproduce

  1. Apply commit af94b8b on top of latest master
  2. Add new test case to test chunked stream encoding, which uses existing test data set but feeds data in a smaller chunks (cipher's blocks sized) instead of whole stream at once
procedure TestTDECGCM.TestEncodeStreamChunked;
begin
  // Use cipher block size as max chunk size
  DoTestEncodeStream_LoadAndTestCAVSData(
    Max(FCipherAES.Context.BlockSize, FCipherAES.Context.BufferSize));
end;
  1. Run test GCM suite and get auth tag failure in new test case

Expected and actual behavior
Test should pass, proving that expected auth tag is generated when streaming data in small chunks.

XTEA cipher algorithm broken

The XTEA cipher algorithm seems to be broken. It differs from the various C-implementations one can find on the internet in so far that brackets are set differently and thus the result differs as well. This is at least the case since DEC V5.2 even if it passes its DUnitTest in DEC 6.0 development, so that also means that the test data is most likely wrong. The source of this test data is unfortunately unclear. It already was that way before I took over maintenance of this library.

A fixed development branch commit should be available soon.

Integer Overflow when hashing a large TFilestream

I was trying to hash large TFileStream (all except the first 10MB of the file). I'm using a 900MB file in testing.
When I call Hash.CalcStream(...) on the TFileStream I get an Integer Overflow exception (EIntOverflow).

Tested with THash_SHA256 and THash_SHA512

To Reproduce
Run the following:

uses DECHash;

procedure TfrmTest.Button1Click(Sender: TObject);
var
  fsIn: TFileStream;
  b: TBytes;
begin

  fsIn:=TFileStream.Create('900MBfile.dat', fmOpenRead);
  try
    fsIn.Seek(10000000, soFromBeginning); //skip the first 10 MB
    b:=HashStream_SHA256(fsIn);
  finally
    fsIn.Free;
  end;

  System.IOUtils.TFile.WriteAllBytes('hash.bytes', b);
end;

function TfrmTest.HashStream_SHA256(s: TFileStream): TBytes;
var
  Hash : THash_SHA256;
  HashResult: TBytes;
begin
  Hash:=THash_SHA256.Create;
  try
    Hash.CalcStream(s, s.Size - s.Position, HashResult);
  finally
    Hash.Free;
  end;

  result:=HashResult;

end;

Expected and actual behavior
Expected HashResult to be populated with the hash bytes and no excpetions raised.
Actual behavior: An exception is thrown when hashing large files using CalcStream().
When I use a small file (around 15MB) there is no exception and it functions as normal.

Implement HMACStream and HMACFile

I want to suggest a combination of the following methods:

  1. TDECHashAuthentication.HMAC combined with TDECHashExtended.CalcStream
  2. TDECHashAuthentication.HMAC combined with TDECHashExtended.CalcFile

Background information: I want to encrypt a large file which does not fit into the memory, and I would like to do "Encrypt-then-HMAC". So I need to HMAC the whole file or stream. (Pre-hasing is not a solution, because it is insecure)

Here is the code I wrote (actually copied and modified) and tested.

type
  TDECHashExtendedAuthentication = class helper for TDECHashAuthentication
    class function HMACFile(const Key: TBytes; const FileName: string;
      const OnProgress:TDECProgressEvent = nil): TBytes;
    class function HMACStream(const Key: TBytes; const Stream: TStream; Size: Int64;
      const OnProgress:TDECProgressEvent = nil): TBytes;
  end;

{ TDECHashExtendedAuthentication }

class function TDECHashExtendedAuthentication.HMACFile(const Key: TBytes;
  const FileName: string; const OnProgress: TDECProgressEvent): TBytes;
var
  fs: TFileStream;
begin
  fs := TFileStream.Create(FileName, fmOpenRead);
  try
    HMACStream(Key, fs, fs.Size, OnProgress);
  finally
    FreeAndNil(fs);
  end;
end;

class function TDECHashExtendedAuthentication.HMACStream(const Key: TBytes;
  const Stream: TStream; Size: Int64;
  const OnProgress: TDECProgressEvent = nil): TBytes;
const
  CONST_UINT_OF_0x36 = $3636363636363636;
  CONST_UINT_OF_0x5C = $5C5C5C5C5C5C5C5C;
var
  HashInstance: TDECHashAuthentication;
  InnerKeyPad, OuterKeyPad: array of Byte;
  I, KeyLength, BlockSize, DigestLength: Integer;
begin
  // Taken from TDECHashAuthentication.HMAC and changed HashInstance.Calc to HashInstance.CalcStream for the message
  HashInstance := TDECHashAuthenticationClass(self).Create;
  try
    BlockSize    := HashInstance.BlockSize; // 64 for sha1, ...
    DigestLength := HashInstance.DigestSize;
    KeyLength    := Length(Key);

    SetLength(InnerKeyPad, BlockSize);
    SetLength(OuterKeyPad, BlockSize);

    I := 0;

    if KeyLength > BlockSize then
    begin
      Result    := HashInstance.CalcBytes(Key);
      KeyLength := DigestLength;
    end
    else
      Result := Key;

    while I <= KeyLength - SizeOf(NativeUInt) do
    begin
      PNativeUInt(@InnerKeyPad[I])^ := PNativeUInt(@Result[I])^ xor NativeUInt(CONST_UINT_OF_0x36);
      PNativeUInt(@OuterKeyPad[I])^ := PNativeUInt(@Result[I])^ xor NativeUInt(CONST_UINT_OF_0x5C);
      Inc(I, SizeOf(NativeUInt));
    end;

    while I < KeyLength do
    begin
      InnerKeyPad[I] := Result[I] xor $36;
      OuterKeyPad[I] := Result[I] xor $5C;
      Inc(I);
    end;

    while I <= BlockSize - SizeOf(NativeUInt) do
    begin
      PNativeUInt(@InnerKeyPad[I])^ := NativeUInt(CONST_UINT_OF_0x36);
      PNativeUInt(@OuterKeyPad[I])^ := NativeUInt(CONST_UINT_OF_0x5C);
      Inc(I, SizeOf(NativeUInt));
    end;

    while I < BlockSize do
    begin
      InnerKeyPad[I] := $36;
      OuterKeyPad[I] := $5C;
      Inc(I);
    end;

    HashInstance.Init;
    HashInstance.Calc(InnerKeyPad[0], BlockSize);
    if Size > 0 then
      TDECHashExtended(HashInstance).CalcStream(Stream, Size, OnProgress, false);
    HashInstance.Done;
    Result := HashInstance.DigestAsBytes;

    HashInstance.Init;
    HashInstance.Calc(OuterKeyPad[0], BlockSize);
    HashInstance.Calc(Result[0], DigestLength);
    HashInstance.Done;

    Result := HashInstance.DigestAsBytes;
  finally
    HashInstance.Free;
  end;
end;

Random padding / Confusion about "IV" padding vs "Last block" padding?

You told me a few days that it would be preferrable if the padding would be randomized instead of static.
I have researched on the topic and indeed, randomized padding for the last block is highly recommended.

I have tried to find out how it currently works, but I believe that the documentation does not fit the code

Documentation:

    /// <param name="IFiller">
    ///   optional parameter defining the value with which the last block will
    ///   be filled up if the size of the data to be processed cannot be divided
    ///   by block size without reminder. Means: if the last block is not
    ///   completely filled with data.
    /// </param>

vs. Implementation (This is the only place where I could see that IFillter is used):

FillChar(FInitializationVector^, FBufferSize, IFiller)

The I is probably also a hint that the filler is the padding of the IV and not the padding of the last block?

So a few questions arrised:

  1. If indeed IFiller is only for the IV, are we safe then? (Because the blocks are dependant on each previous block, so the padding of the last block will be rather unguessable.) Edit: To answer my own question: We might be more safe if we'd use the standard PKCS#7 to fill the last block.
  2. I am not 100% sure what this does: FillChar(FInitializationVector^, FBufferSize, IFiller) Why is the IV filled with the length of the buffer size, and not with the length of the block? I thought the IV only needs the size of a single block, and not the size of the buffer?

In case we want random padding, I guess we could use TBlockFillMode for this purpose; something like:

  if FillMode = fmByte then
    FillChar(FInitializationVector^, FBufferSize, IFiller)
  else if FillMode = fmRandomByte then
    FillChar(FInitializationVector^, FBufferSize, ....Random stuff....);

Edit: Actually, if we use TBlockFillMode as it is intended to be (to fill the last block instead of the IV), then it might be good to have it actually be defined as (fmByte, fmRandom, fmPkcs5, fmPkcs7) where fmByte is defined as constant byte.

A ManualRegisterClasses define would be nice

A define akin to DEC 3.0's ManualRegisterClasses would be nice to have. All the XXX.RegisterClass() calls in "initialization" section of a few modules could be surrounded by {$IFNDEF ManualRegisterClasses}.

The define could be placed in DECOptions.inc as disabled by default.

Error on compiling for Linux

If I compile the Library for Linux as target Plattform an error occurs:

[DCC Fehler] DECHash.pas(325): E2100 Datentyp zu groß: 2 GB überschritten

Line 325 in DECHash:

TBABytes = array[0..MaxLongInt-1] of UInt8;

Add cipher demo that uses a KDF and a currently unbroken cipher

The simple cipher demo does not use a KDF to generate a key and instead uses a password that has the right length to be accepted by the used cipher. Since developers (myself included) often start with copying code from the demo, it would be cool, if there was a demo, that uses the library in a safe way with an unbroken cipher.
The goal here is, that developers, which are new to cryptography or this library, won't end up with weak encryption in their projects.

Decrypting long data is impossible?

I try decrypt array of byte, size of array is 70 bytes, data is encrypted with MARS algorithm, although the problem is probably different than the algorithm.

I call DecodeBytes method:

function TDECCipher.DecodeBytes(const Source: TBytes; Format: TDECFormatClass): TBytes;
begin
  SetLength(Result, 0);
  if Length(Source) > 0 then
  begin
    Result := ValidFormat(Format).Decode(Source);
    DoDecode(@Result[0], @Result[0], Length(Result) * SizeOf(Result[0]));
  end;
end;

And this method calls a method from the class implementing the MARS algorithm and I have an exception right on the first line:

procedure TCipher_Mars.DoDecode(Source, Dest: Pointer; Size: Integer);
var
  K: PUInt32Array;
  I, L, R, A, B, C, D: UInt32;
begin
  Assert(Size = Context.BlockSize); << I get this exception because source data size is 70 but BlockSize is 16

In old DEC library version the Decode method looked like this:


procedure TDECCipher.Decode(const Source; var Dest; DataSize: Integer);
begin
  CheckState([csInitialized, csDecode, csDone]);
  case FMode of
    cmECBx: DecodeECBx(@Source, @Dest, DataSize);
    cmCBCx: DecodeCBCx(@Source, @Dest, DataSize);
    cmCTSx: DecodeCTSx(@Source, @Dest, DataSize);
    cmCFB8: DecodeCFB8(@Source, @Dest, DataSize);
    cmCFBx: DecodeCFBx(@Source, @Dest, DataSize);
    cmOFB8: DecodeOFB8(@Source, @Dest, DataSize);
    cmOFBx: DecodeOFBx(@Source, @Dest, DataSize);
    cmCFS8: DecodeCFS8(@Source, @Dest, DataSize);
    cmCFSx: DecodeCFSx(@Source, @Dest, DataSize);
  end;
end;

And each method dependent on the encoding mode had a loop, dividing the data into blocks.
Eg.:

  procedure DecodeECBx(S,D: PByteArray; Size: Integer);
  var
    I: Integer;
  begin
    if Context.BlockSize = 1 then
    begin
      DoDecode(S, D, Size);
      FState := csDecode;
    end else
    begin
      Dec(Size, FBufferSize);
      I := 0;
      while I <= Size do
      begin
        DoDecode(@S[I], @D[I], FBufferSize);
        Inc(I, FBufferSize);
      end;
      Dec(Size, I - FBufferSize);
      if Size > 0 then
        if Size mod Context.BlockSize = 0 then
        begin
          DoDecode(@S[I], @D[I], Size);
          FState := csDecode;
        end else
        begin
          FState := csPadded;
          InvalidMessageLength(Self);
        end;
    end;
  end;

Where is this loop currently implemented?

"VCL" vs "VLC" typo in samples

In the demos, there is a typo "VLC" instead of "VCL".

Since it affects renaming files, I feel more secure if you do it directly instead of a pull request.

Thank you!

Change IV

The literature describes that the initial vector (IV) should not be constant.
I have therefore changed the code so that the IV is also changed each time the key is changed.
I realized this with the help of a hash of the key in truncated length (12).
Then I set OnChange and OnTyping of the editKey.
I hope that I have communicated this correctly.

procedure TFormMain.EditInitVectorChange(Sender: TObject);
var InitV : string; //vom Key wird ein Hash genutzt, um den InitVector zu bestimmen (OnChange und OnTyping von editKey setzen)
begin
InitV := THashSHA2.GetHashString(EditKey.Text, THashSHA2.TSHA2Version.SHA224).ToLower;
EditInitVector.text:=Copy (InitV,0,12);
end;

Missing padding for ECB mode

Describe the bug
I used FMX Cipher Demo to use both AES and DES encryptions to make them work with this site : https://www.devglan.com/online-tools/aes-encryption-decryption

The issue comes when you select ECB cipher mode but message length is not a multiple of 8

I already spent a lot of time with other Delphi encryption libraries and found this post years ago explaining ECB needs padding as well
https://stackoverflow.com/questions/55137264/lockbox-3-encrypting-not-matching-online-tool-suspect-padding-or-key-problem

PKCS5PadStringToBytes function described in the post solved my problem, please find below the part of code updated
`
function PKCS5PadStringToBytes(RawData: string; const PadSize: integer): System.SysUtils.TBytes;
var
DataLen: integer;
PKCS5PaddingCount: ShortInt;
begin
result := TEncoding.UTF8.GetBytes(RawData);
DataLen := Length(RawData);

PKCS5PaddingCount := PadSize - DataLen mod PadSize;
if PKCS5PaddingCount = 0 then
PKCS5PaddingCount := PadSize;
Inc(DataLen, PKCS5PaddingCount);

SetLength(result, DataLen);
FillChar(result[DataLen - PKCS5PaddingCount], PKCS5PaddingCount, PKCS5PaddingCount);
end;

procedure TFormMain.ButtonEncryptClick(Sender: TObject);
var
Cipher: TDECCipherModes;
InputFormatting: TDECFormatClass;
OutputFormatting: TDECFormatClass;
InputBuffer: TBytes;
OutputBuffer: TBytes;
begin
if not GetFormatSettings(InputFormatting, OutputFormatting) then
exit;

try
Cipher := GetInitializedCipherInstance;

try
  InputBuffer := System.SysUtils.BytesOf(EditPlainText.Text);

  if GetSelectedCipherMode = cmECBx then
  begin
     InputBuffer := PKCS5PadStringToBytes(EditPlainText.Text, 8);
  end;

...`

I wonder why you explicitly ignore padding in ECB mode ?

You will find below a screenshot with my fix, matching demo result with the website

image

DECCipherFormats.DecodeStringToString most likely broken

As I'm currently writing unit tests for the DECCipherFormats unit I encountered that the DecodeStringToString method for unicode strings (normal string type) is most likely broken.
It produces different output compared to DecodeStringToBytes on the bytewise same input data.

I'll try to investigate further and fix it, but it might need further time.

Access violation if GCM mode is set after cipher is initialized

To Reproduce

  1. Open demo project Cipher_Console
  2. Change Cipher.Mode to cmGCM
  3. Run the code. You receive EAccessViolation

Usually, if you change the cipher mode after the cipher has been initialized, then TDECCipher.SetMode should call Done on the cipher and re-initialize it.

GCM Encode requires that TGCM.Init is called and has set FEncryptionMethod := EncryptionMethod. However, if Ciper.Mode is set after the cipher has been initialized, then TGCM is created but TGCM.Init has not been called.

procedure TDECCipherModes.InitMode;
begin
  if FMode = TCipherMode.cmGCM then
  begin
    if Context.BlockSize = 16 then
      FGCM := TGCM.Create
    else
      // GCM requires a cipher with 128 bit block size
      raise EDECCipherException.CreateResFmt(@sInvalidBlockSize,
                                             [128, GetEnumName(TypeInfo(TCipherMode),
                                             Integer(FMode))]);
  end
  else
    if Assigned(FGCM) then
      FreeAndNil(FGCM);
end;

The program flow if Mode has been set before init:

  1. TDECCipher.Init()
  2. TDECCipher.Init()
  3. TDECCipherModes.OnAfterInitVectorInitialized ( calls FGCM.Init(self.DoEncode, OriginalInitVector) )
  4. TGCM.Init

The program flow if Mode has been set after init:

  1. TDECCipher.SetMode
  2. TDECCipherModes.InitMode
  3. TGCM.Create, but not TGCM.Init ( I am not sure where I get OriginalInitVector from )

So... what do we do? We probably need to preserve the InitVector, so we can call TGCM.Init with the correct parameters.

The other solution is to forbid to change the mode after the cipher has been initialized. But this is a code breaking change.

Testcases failure

(as previously mentioned in #62 )

I am using Delphi 11, have compiled DEC60.exe to compile the DCU files and then immediately compiled and ran DECUnitTestSuite.exe

There are the following problems "out of the box":

  1. Data\Keccak.rsp is missing. Did you forget to include this test file in GitHub? Therefore all tests in TestTHash_Keccak_224 fail with EFOpenError.

image

  1. Other tests in TestTHash_Keccak_256, 384, 512 fail with ETestFailure. (Maybe this will automatically fixed if the RSP file is added?)

image

  1. TestTDECGCM : TestEncodeSTreamChunked fails with:
TestEncodeStreamChunked: ETestFailure
at  $00344DD3
Authentication tag wrong for Key 9971071059abc009e4f2bd69869db338 IV 07a9a95ea3821e9c13c63251 PT f54bc3501fed4f6f6dfb5ea80106df0bd836e6826225b75c0222f6e859b35983 AAD Exp.:  Act.: , expected: <7870d9117f54811a346970f1de090c41> but was: <12dee761e7034c3fe993d7bfb3389aa9>

image

The vector is from gcmEncryptExtIV128.rsp

[Keylen = 128]
[IVlen = 96]
[PTlen = 256]
[AADlen = 0]
[Taglen = 128]

Count = 0
Key = 9971071059abc009e4f2bd69869db338
IV = 07a9a95ea3821e9c13c63251
PT = f54bc3501fed4f6f6dfb5ea80106df0bd836e6826225b75c0222f6e859b35983
AAD = 
CT = 0556c159f84ef36cb1602b4526b12009c775611bffb64dc0d9ca9297cd2c6a01
Tag = 7870d9117f54811a346970f1de090c41

I guess this is the same as #52 (comment)

Does not compile under Delphi x64

Describe the bug
Tried to compile my test application for x64 using Delphi 10.4.1 commandline compiler, and it failed with errors:

DECCiphers.pas(977) Error: E2010 Incompatible types: 'PBlowfish' and 'PByteArray'
DECCiphers.pas(1051) Error: E2010 Incompatible types: 'PBlowfish' and 'PByteArray'
DECCiphers.pas(2427) Error: E2010 Incompatible types: 'PUInt32Array' and 'PByteArray'
DECCiphers.pas(4726) Error: E2010 Incompatible types: 'PUInt32Array' and 'PByteArray'

To Reproduce
It can be reproduced straight away from your original sources package

  1. Go to the Sources folder
  2. Issue dcc32 -nsWinApi;System DEC60.dpr - compiles fine
  3. Issue dcc64 -nsWinApi;System DEC60.dpr - fails with above errors

Migration from old DEC library

I am trying to migrate from the archaic DEC version to the current one. I have written my own wrapper for the old version of the library and I use this wrapper in my projects.
But I see very many changes in the new DEC, I have dozens of compilation errors. Please give me some words how to approach this migration.

I noticed for example that the new DEC is focused on using TBytes type, am I right? What else to pay attention to?

Range Check Error in TDECCipherModes.EncodeCBCx()

Describe the bug
In DEC (6.4.1) when using block cipher, e.g. AES or DES, I encounter range check error exception in DECCipherModes.pas (2022-02-27), TDECCipherModes.EncodeCBCx() when encrypting blocks larger than 32 KiB.
It happens because the block cipher type for Source and Dest is PByteArray.
PByteArray is defined in Delphi RTL System.SysUtils (Delphi 10.2, 10.3) as:

type
...
  PByteArray = ^TByteArray;
  TByteArray = array[0..32767] of Byte;

To Reproduce
1, Enable range check error in compiler options
2. Call a function like this:

function AESEncryptSomething(): TBytes;  
begin
  SetLength(SouceTab, 256*1024);  // Size >32 KiB

  AESCipher:=TCipher_AES.Create;
  AESCipher.Init(AESKey, IV, 0);  // Key and InitVector
  AESCipher.Mode:=cmCBCx;
  Result:=AESCipher.EncodeBytes(SourceTab);  // Range check error!
  FreeAndNil(AESCipher);
end;

Expected and actual behavior
As an user of the DEC lib, your work around method could be to disable range checking for your whole application in the Delphi compiler settings. However that is not a good option.

Alternative work around is in DECCipherModes.pas just after implementation keyword to disable range check for rest of unit. Do:

implementation
{$R-}

To resolve this problem I recommend that DEC lib should rather define and use its own byte data block type, something like:

TDECByteArray = array[0..MaxInt-1] of Byte;

no compile on Linux

I tried to compile 3de on linux, and got

C:\.....\DelphiEncryptionCompendium\DECUtil.pas(627,24): error E2003: E2003 Undeclared identifier: 'GetTickCount64'
Captura de Pantalla 2022-11-22 a la(s) 12 29 23

FMX on windows works fine
with TCipher_3DES.Create do
try
Mode:=cmCBCx;
Init('5oquil2oo2vb63e8ionujny6','12345678');
Decoded := DecodeBinary ('y/3R651R/AnKxkdtFkUZpihKnpKe9Orx',TFormat_MIME64 );
Free;
end;

Broken ciphers on x64 platform

The following cipher algorithms do not properly pass their unit tests on x64 currently:

  • Blowfish
  • RC6
  • Q128

They do pass their unit tests on x32 platform.
I haven't tested this on mobile platforms yet.

Any help in testing and fixing these issues is welcome.

THash_SHA1.PBKDF2 create wrong Results

Calling THash_SHA1.PBKDF2 produces incorrect or different results for different key lengths:

THash_SHA1.PBKDF2('PassWord', 'Salt', 1000, 16)
returns
(5, 231, 179, 63, 147, 234, 29, 53, 147, 155, 50, 173, 89, 148, 239, 99).

THash_SHA1.PBKDF2('PassWord', 'Salt', 1000, 32)
returns
(25, 19, 104, 233, 243, 31, 227, 133, 0, 222, 240, 86, 147, 7, 76, 55, 22, 159, 117, 140, 25, 19, 104, 233, 243, 31, 227, 133, 0, 222, 240, 86)

THash_SHA1.PBKDF2('PassWord', 'Salt', 1000, 48)
returns
(25, 19, 104, 233, 243, 31, 227, 133, 0, 222, 240, 86, 147, 7, 76, 55, 22, 159, 117, 140, 25, 19, 104, 233, 243, 31, 227, 133, 0, 222, 240, 86, 147, 7, 76, 55, 22, 159, 117, 140, 159, 45, 208, 2, 26, 124, 20, 230)

My understanding is that the first 16 bytes of the result should be identical in all cases. Unfortunately this is not the case.

Installing in Delphi 2010

Not so sure this is a bug, but I want to use the compendium in D2010 and having trouble.
I certainly don't want to use the installer project as I don't want it installed everywhere, but from what I could see, it basically just installs library paths, which I have done manually for a test project.
It has also been written for Delphi versions greater than D2010 since the uses clause for example is like:

uses
System.SysUtils,
System.Win.Registry,
System.Classes;

which don't work for D2010 and changing these just leads me further down a rabbit hole.

Anyhow, just setting the path in the project options then gives me the compiler error:

[DCC Error] DECOptions.inc(98): E2029 $IFEND expected but $ENDIF found

{$IFDEF FPC }
{$IF defined(CPUX86_64) or defined(CPUAMD64) or defined(CPUIA64) }
{$ifndef CPUX64}
{$define CPUX64}
{$endif}
{$else}{$if defined(CPU386) or defined(CPUI386) }
{$ifndef CPUX32}
{$define CPUX32}
{$endif}
{$ELSE}
{$IFNDEF ASSEMBLER }
{$DEFINE NO_ASM} (* default ON )
{$ELSE}
{$IFDEF WINDOWS}
{.$DEFINE NO_ASM} (
default OFF )
{$ELSE}
{$DEFINE NO_ASM} (
default ON *)
{$ENDIF}
{$ENDIF}
{$ENDIF}{$endif} // line 98
{$ELSE}
// Turn ASM off for FPC as we do not know enough about ASM support on FPC
{$DEFINE NO_ASM}
{$ENDIF}

FPC is not set so don't see why that line is even reached.
Removing what looks like an extra {$endif} doesn't help.
Had some success replacing both the {$ENDIF}{$endif} with {$IFEND}{$ifend}, which required me to start removing the 'system.' prefix of a lot of the uses clauses in many other units, but that rabbit hole got to deep with other errors that I won't go into here.

If I set FPC then I just get an error in Indy10 with:

[DCC Error] IdCompilerDefines.inc(528): E1030 Invalid compiler directive: 'MODE'

So the question I'm asking is, has anyone got this working with D2010 recently and can they tell me what I should do?

Hash FMX demo crashes on Android 32 bit in release mode

The Hash FMX demo app crashes when compiled as release mode Android 32 app. When compiled as Android 32 bit debug mode app it works. The reason is not known yet but it will be investigated.

Some user reported that this code is sufficient to crash it already:
`uses
DECHash

var
Hash: THash_MD5;
begin

Hash := THash_MD5.Create;
Try
sleep(1000);
Finally
Hash.Free;
End;`

Version 6.4 broke 2DES output

Decrypting data and encrypting back the result of first step should output the starting value.
This has been broken with lastest version, using class TCipher_2DES. Not tested all the des function, possible bug also in other des classes due the new refactoring on the DES unit.

Test output with version 6.4

DES/CBC (DEC 6.4)-----------------------------
Key : 0011223344556677
Data : B71FAAB72D3C4F50
Decrypt : 8FE5901009548428
Encrypt : B71FAAB72D3C4F50
Match : True

2DES/CBC (DEC 6.4)----------------------------
Key : 00112233445566778899AABBCCDDEEFF
Data : B71FAAB72D3C4F50
Decrypt : 8FE5901009548428
Encrypt : 45C874C1880C21FB
Match : >>>>> FALSE <<<<<

AES/CBC (DEC 6.4)-----------------------------
Key : 00112233445566778899AABBCCDDEEFF
Data : B71FAAB72D3C4F50B71FAAB72D3C4F50
Decrypt : 0899A8624B026B88E9238173EB5B5475
Encrypt : B71FAAB72D3C4F50B71FAAB72D3C4F50
Match : True

Test output with version 6.3

DES/CBC (DEC 6.3)-----------------------------
Key : 0011223344556677
Data : B71FAAB72D3C4F50
Decrypt : 8FE5901009548428
Encrypt : B71FAAB72D3C4F50
Match : True

2DES/CBC (DEC 6.3)----------------------------
Key : 00112233445566778899AABBCCDDEEFF
Data : B71FAAB72D3C4F50
Decrypt : 31C35143663E7A00
Encrypt : B71FAAB72D3C4F50
Match : True

AES/CBC (DEC 6.3)-----------------------------
Key : 00112233445566778899AABBCCDDEEFF
Data : B71FAAB72D3C4F50B71FAAB72D3C4F50
Decrypt : 0899A8624B026B88E9238173EB5B5475
Encrypt : B71FAAB72D3C4F50B71FAAB72D3C4F50
Match : True

Key length over 16 characters with exception

I have used a key with 18 digits and get an exception afterwards: Keymaterial is too large for use (securityissue).
With a key of 16 characters the program runs without errors.

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected and actual behavior
A clear and concise description of what you expected to happen
and what you see happening.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

Implement Tiger128 and 160 hash algorithms

This is the only really left thing of #2:
implement the Tiger128 and Tiger160 hash algorithms.

While this can be done and will eventually done importance of this is considered to be low.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.