Jump to content
TurboMagic

Specification IEEE P1363

Recommended Posts

Hello,

 

in order to decide how to properly fix this issue in DEC (Delphi Encryption Compendium) I would like to look up the exact original definition
of the KDF algorithms for the case of an empty key/password being given as argument. Unfortunately that is in some IEEE paper/standard,
which is behind a paywal. Is there anybody having access to IEEE P1363?

 

Here's the DEC issue:

https://github.com/MHumm/DelphiEncryptionCompendium/issues/76

 

Cheers

TurboMagic

Share this post


Link to post

Hi,

 

I looked at the implementation at 

https://github.com/MHumm/DelphiEncryptionCompendium/blob/master/Source/DECHashAuthentication.pas#L997-L1049

and lets say this one

https://github.com/MHumm/DelphiEncryptionCompendium/blob/master/Source/DECHashAuthentication.pas#L1067-L1074

 

class function TDECHashAuthentication.KDF1(const Data, Seed: TBytes;
  MaskSize: Integer): TBytes;
begin
  if (length(Seed) > 0) then
    Result := KDFInternal(Data[0], length(Data), Seed[0], length(Seed), MaskSize, ktKDF1)
  else
    Result := KDFInternal(Data[0], length(Data), NullStr, 0, MaskSize, ktKDF1);
end;

The problem is easy to see and and easy to fix here, but lets point the cause

Data is TBytes, in other words managed type and if Data is empty then Data is nil, and that is it, accessing Data from 

class function TDECHashAuthentication.KDFInternal(const Data; DataSize: Integer; const Seed;
                             SeedSize, MaskSize: Integer; KDFType: TKDFType): TBytes;
var
  I, n,
  Rounds, DigestBytes : Integer;
  Count               : UInt32;
  HashInstance        : TDECHashAuthentication;
begin
  SetLength(Result, 0);
  DigestBytes := DigestSize;
  Assert(MaskSize >= 0);
  Assert(DataSize >= 0);
  Assert(SeedSize >= 0);
  Assert(DigestBytes >= 0);

  HashInstance := TDECHashAuthenticationClass(self).Create;
  try
    Rounds := (MaskSize + DigestBytes - 1) div DigestBytes;
    SetLength(Result, Rounds * DigestBytes);

    if (KDFType = ktKDF2) then
      n := 1
    else
      n := 0;

    for I := 0 to Rounds-1 do
    begin
      Count := SwapUInt32(n);
      HashInstance.Init;

      if (KDFType = ktKDF3) then
      begin
        HashInstance.Calc(Count, SizeOf(Count));
        HashInstance.Calc(Data, DataSize);			//  <-------- here Data can't be nil
      end
      else
      begin
        HashInstance.Calc(Data, DataSize);
        HashInstance.Calc(Count, SizeOf(Count));		//  <-------- here Data can't be nil
      end;

      HashInstance.Calc(Seed, SeedSize);
      HashInstance.Done;
      Move(HashInstance.Digest[0], Result[(I) * DigestBytes], DigestBytes);

Also as designed, i mean KDFx it does hash the concatenation of Data with the seed, if data is nil then just skip it, and that is the fix.

 

As for your request the specification, then check your private messages, as i attached IEEE 1363-2000 and an old draft of ISO/IEC 18033-2.

Share this post


Link to post

On side note KDF(x) are key driving functions, but these functions are old and mainly used for specific purposes, which generating a key from a key or sufficient and accepted entropy, they never meant to be used for passwords and for that they had the seed added, they should have have been designed better to focus on this issue, not like PBKDF which is Password Based Key Deriving Function, which designed to be get a key from low entropy sources like password and it compensate with arbitrary rounds of HMAC.

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×