Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2013-03

HMAC_SHA1 and FPC

57 messages · 14 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

David Butler
to silvioprog

Hi

You can find a hash library that supports HMAC-SHA1 here:

http://fundementals.sourceforge.net/dl.html

silvioprog wrote 17 lines
Hello, How to get HMAC_SHA1 using native functions of FPC? HMAC_SHA1: http://en.wikipedia.org/wiki/Hash-based_message_authentication_code#Examples_of_HMAC_.28MD5.2C_SHA1.2C_SHA256.29 Thank you! -- Silvio Clécio My public projects - github.com/silvioprog _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Tony Whyman
to silvioprog: How to get HMAC_SHA1 using native functions of FPC? HMAC_SHA1:…

Silvio,

I had the same requirement for an HMAC and used the DCP library:

http://wiki.freepascal.org/DCPcrypt

I then used the following code snippet to generate the HMAC

Regards

Tony Whyman
MWA

unit hmac;
{$mode objfpc}{$H+}
interface
uses
  Classes, SysUtils;
procedure MakeHMAC(text: string; var seed: LongInt; var hash: string);
function ValidateHMAC(text: string; seed: LongInt; hmac: string): boolean;
implementation
uses DCPsha1;
function GenerateHash(seed: longint; data: string):string;
var b1, b2, b3, b4: byte;
    q: integer;
    sha1: TDCP_sha1;
    buffer: PChar;
    memsize: integer;
    len: integer;
begin
  len := Length(data);
  b1 := seed mod 256;
  q := seed div 256;
  b2 := q mod 256;
  q := q div 256;
  b3 := q mod 256;
  b4 := q div 256;
  sha1 := TDCP_sha1.Create(nil);
  try
    sha1.Init;
    memsize := len + 4;
    buffer := SysGetMem(memsize);
    try
      Move(b1,buffer^,1);
      Move(b2,(buffer+1)^,1);
      Move(b3,(buffer+2)^,1);
      Move(b4,(buffer+3)^,1);
      Move(data[1],(buffer+4)^,len);
      SHA1.Update(buffer^,len+4);
      setlength(Result,20);
      SHA1.Final(Result[1]);
    finally
      SysFreeMem(buffer);
    end;
  finally
    sha1.free;
  end;
end;
procedure MakeHMAC(text: string; var seed: LongInt;
  var hash: string);
begin
       Randomize;
       seed := Round(Random(MaxLongInt));
       hash := GenerateHash(seed,text);
       hash := GenerateHash(seed,hash);
end;
function ValidateHMAC(text: string; seed: LongInt; hmac: string): boolean;
var hash1, hash2: string;
begin
  hash1 := GenerateHash(seed,text);
  hash2 := GenerateHash(seed,hash1);
  Result := CompareMem(@(hmac[1]),@(hash2[1]),20)
end;
end.
silvioprog wrote 17 lines
Hello, How to get HMAC_SHA1 using native functions of FPC? HMAC_SHA1: http://en.wikipedia.org/wiki/Hash-based_message_authentication_code#Examples_of_HMAC_.28MD5.2C_SHA1.2C_SHA256.29 Thank you! -- Silvio Clécio My public projects - github.com/silvioprog <http://github.com/silvioprog> _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

silvioprog
to Tomas Hajny: Doesn't package hash (included with FPC by default for all targets) cover your needs?…

2013/3/23 Tomas Hajny

Show quoted text 14 lines
On Sat, March 23, 2013 06:28, silvioprog wrote: Hi, > How to get HMAC_SHA1 using native functions of FPC? > > HMAC_SHA1: > http://en.wikipedia.org/wiki/Hash-based_message_authentication_code#Examples_of_HMAC_.28MD5.2C_SHA1.2C_SHA256.29 Doesn't package hash (included with FPC by default for all targets) cover your needs? Tomas

Yes, the "sha1" unit, but how to do it? I was seeing a function in PHP, but I couldn't port it to the Free Pascal.

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

silvioprog
to Tony Whyman: I had the same requirement for an HMAC and used the DCP library:…

2013/3/23 Tony Whyman

Show quoted text 86 lines
Silvio, I had the same requirement for an HMAC and used the DCP library: http://wiki.freepascal.org/DCPcrypt I then used the following code snippet to generate the HMAC Regards Tony Whyman MWA unit hmac; {$mode objfpc}{$H+} interface uses Classes, SysUtils; procedure MakeHMAC(text: string; var seed: LongInt; var hash: string); function ValidateHMAC(text: string; seed: LongInt; hmac: string): boolean; implementation uses DCPsha1; function GenerateHash(seed: longint; data: string):string; var b1, b2, b3, b4: byte; q: integer; sha1: TDCP_sha1; buffer: PChar; memsize: integer; len: integer; begin len := Length(data); b1 := seed mod 256; q := seed div 256; b2 := q mod 256; q := q div 256; b3 := q mod 256; b4 := q div 256; sha1 := TDCP_sha1.Create(nil); try sha1.Init; memsize := len + 4; buffer := SysGetMem(memsize); try Move(b1,buffer^,1); Move(b2,(buffer+1)^,1); Move(b3,(buffer+2)^,1); Move(b4,(buffer+3)^,1); Move(data[1],(buffer+4)^,len); SHA1.Update(buffer^,len+4); setlength(Result,20); SHA1.Final(Result[1]); finally SysFreeMem(buffer); end; finally sha1.free; end; end; procedure MakeHMAC(text: string; var seed: LongInt; var hash: string); begin Randomize; seed := Round(Random(MaxLongInt)); hash := GenerateHash(seed,text); hash := GenerateHash(seed,hash); end; function ValidateHMAC(text: string; seed: LongInt; hmac: string): boolean; var hash1, hash2: string; begin hash1 := GenerateHash(seed,text); hash2 := GenerateHash(seed,hash1); Result := CompareMem(@(hmac[1]),@(hash2[1]),20) end; end.

Very nice. I will analyze this routine and see if I can remove the dependence of DCP library. Thank you!

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

Tony Whyman
to silvioprog

Silvio,

Just one extra point - the snippet I sent is example code. It is not intended to be RFC compliant.

Regards

Tony Whyman
MWA

silvioprog wrote 103 lines
2013/3/23 Tony Whyman < > Silvio, I had the same requirement for an HMAC and used the DCP library: http://wiki.freepascal.org/DCPcrypt I then used the following code snippet to generate the HMAC Regards Tony Whyman MWA unit hmac; {$mode objfpc}{$H+} interface uses Classes, SysUtils; procedure MakeHMAC(text: string; var seed: LongInt; var hash: string); function ValidateHMAC(text: string; seed: LongInt; hmac: string): boolean; implementation uses DCPsha1; function GenerateHash(seed: longint; data: string):string; var b1, b2, b3, b4: byte; q: integer; sha1: TDCP_sha1; buffer: PChar; memsize: integer; len: integer; begin len := Length(data); b1 := seed mod 256; q := seed div 256; b2 := q mod 256; q := q div 256; b3 := q mod 256; b4 := q div 256; sha1 := TDCP_sha1.Create(nil); try sha1.Init; memsize := len + 4; buffer := SysGetMem(memsize); try Move(b1,buffer^,1); Move(b2,(buffer+1)^,1); Move(b3,(buffer+2)^,1); Move(b4,(buffer+3)^,1); Move(data[1],(buffer+4)^,len); SHA1.Update(buffer^,len+4); setlength(Result,20); SHA1.Final(Result[1]); finally SysFreeMem(buffer); end; finally sha1.free; end; end; procedure MakeHMAC(text: string; var seed: LongInt; var hash: string); begin Randomize; seed := Round(Random(MaxLongInt)); hash := GenerateHash(seed,text); hash := GenerateHash(seed,hash); end; function ValidateHMAC(text: string; seed: LongInt; hmac: string): boolean; var hash1, hash2: string; begin hash1 := GenerateHash(seed,text); hash2 := GenerateHash(seed,hash1); Result := CompareMem(@(hmac[1]),@(hash2[1]),20) end; end. Very nice. I will analyze this routine and see if I can remove the dependence of DCP library. Thank you! -- Silvio Clécio My public projects - github.com/silvioprog <http://github.com/silvioprog> _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

silvioprog
to Tony Whyman

2013/3/23 Tony Whyman

Show quoted text 10 lines
Silvio, Just one extra point - the snippet I sent is example code. It is not intended to be RFC compliant. Regards Tony Whyman MWA

Thank you friend for the answer!

So, seems the Synapse library has the function I'm looking for. I'll compare it with PHP function and if it make hash correctly, I believe that I'll isolate only the part that interests me hehe... :)

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

silvioprog
to silvioprog

Hello,

I could be wrong, but I think that Synapse function have a bug. See:

Using PHP:
<?php
echo hash_hmac("ripemd160", "The quick brown fox jumped over the lazy dog.", "secret");
?>
Result:
b8e7ae12510bdfb1812e463a7f086122cf37e4f7

Using the http://www.freeformatter.com site
Result:
5d4db2701c7b07de0e23db3e4f22e88bc1a31a49

Using Synapse:
uses

  synacode;

begin
Write(HMAC_SHA1('The quick brown fox jumped over the lazy dog.', 'secret');
end.
Result:
]M?p { ? #?>O"?c I

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

silvioprog
to silvioprog

Other PHP function:

<?php
function hmac_sha1($data, $key, $raw_output=FALSE) {
$block_size = 64;   // SHA-1 block size

if (strlen($key) > $block_size) {
$k = pack("H*", sha1($key));
} else {
$k = str_pad($key, $block_Size, "\x00", STR_PAD_RIGHT); }

$ki = '';
 for($i = 0; $i < $block_size; $i++) {
$ki .= chr(ord(substr($k, $i, 1)) ^ 0x36);
}
 $ko = '';
for($i = 0; $i < $block_size; $i++) {
$ko .= chr(ord(substr($k, $i, 1)) ^ 0x5C);
 }

$h = sha1($ko . pack('H*', sha1($ki . $data)));
if ($raw_output) {
return pack('H*', $h);
} else {
return $h;
}
}

echo hmac_sha1("The quick brown fox jumped over the lazy dog.", "secret");
?>

Result:

5d4db2701c7b07de0e23db3e4f22e88bc1a31a49

2013/3/23 silvioprog

Show quoted text 26 lines
Hello, I could be wrong, but I think that Synapse function have a bug. See: Using PHP: <?php echo hash_hmac("ripemd160", "The quick brown fox jumped over the lazy dog.", "secret"); ?> Result: b8e7ae12510bdfb1812e463a7f086122cf37e4f7 Using the http://www.freeformatter.com site Result: 5d4db2701c7b07de0e23db3e4f22e88bc1a31a49 Using Synapse: uses synacode; begin Write(HMAC_SHA1('The quick brown fox jumped over the lazy dog.', 'secret'); end. Result: ]M?p { ? #?>O"?c I
Silvio Clécio My public projects - github.com/silvioprog

Reply by email

David Butler
to silvioprog: 2013/3/23 David Butler But it's not native in Free Pascal. x( Silvio Clécio My public…

What do you mean by "native"?

It is pure pascal code that compiles under Delphi and FreePascal.

Using it is as easy as:

SHA1DigestToHexA(CalcHMAC_SHA1('secret', 'message')

silvioprog wrote 19 lines
2013/3/23 David Butler > Hi > > You can find a hash library that supports HMAC-SHA1 here: > > http://fundementals.sourceforge.net/dl.html > But it's not native in Free Pascal. x( -- Silvio Clécio My public projects - github.com/silvioprog _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

silvioprog
to David Butler

2013/3/23 David Butler

Show quoted text 8 lines
What do you mean by "native"? It is pure pascal code that compiles under Delphi and FreePascal. Using it is as easy as: SHA1DigestToHexA(CalcHMAC_SHA1('secret', 'message')

To not implement a big code like this:

unit Unit1;
{$mode objfpc}{$H+}
interface
uses
  Forms, StdCtrls;
type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  end;
  T512BitBuf  = array[0..63] of Byte;
  T160BitDigest = record
    case integer of
      0 : (Longs : array[0..4] of LongWord);
      1 : (Words : array[0..9] of Word);
      2 : (Bytes : array[0..19] of Byte);
    end;
var
  Form1: TForm1;
implementation
{$R *.lfm}
procedure SHA1InitDigest(var Digest: T160BitDigest);
begin
  Digest.Longs[0] := $67452301;
  Digest.Longs[1] := $EFCDAB89;
  Digest.Longs[2] := $98BADCFE;
  Digest.Longs[3] := $10325476;
  Digest.Longs[4] := $C3D2E1F0;
end;
function RotateLeftBits(const Value: LongWord; const Bits: Byte): LongWord;
var I : Integer;
begin
  Result := Value;
  for I := 1 to Bits do
    if Result and $80000000 = 0 then
      Result := Value shl 1 else
      Result := (Value shl 1) or 1;
end;
procedure TransformSHABuffer(var Digest: T160BitDigest; const Buffer; const
SHA1: Boolean);
var A, B, C, D, E : LongWord;
    W : array[0..79] of LongWord;
    P, Q : PLongWord;
    I : Integer;
    J : LongWord;
begin
  P := @Buffer;
  Q := @W;
  for I := 0 to 15 do
    begin
      Q^ := SwapEndian(P^);
      Inc(P);
      Inc(Q);
    end;
  for I := 0 to 63 do
    begin
      P := Q;
      Dec(P, 16);
      J := P^;
      Inc(P, 2);
      J := J xor P^;
      Inc(P, 6);
      J := J xor P^;
      Inc(P, 5);
      J := J xor P^;
      if SHA1 then
        J := RotateLeftBits(J, 1);
      Q^ := J;
      Inc(Q);
    end;
  A := Digest.Longs[0];
  B := Digest.Longs[1];
  C := Digest.Longs[2];
  D := Digest.Longs[3];
  E := Digest.Longs[4];
  P := @W;
  for I := 0 to 3 do
    begin
      Inc(E, (A shl 5 or A shr 27) + (D xor (B and (C xor D))) + P^ +
$5A827999); B := B shr 2 or B shl 30; Inc(P);
      Inc(D, (E shl 5 or E shr 27) + (C xor (A and (B xor C))) + P^ +
$5A827999); A := A shr 2 or A shl 30; Inc(P);
      Inc(C, (D shl 5 or D shr 27) + (B xor (E and (A xor B))) + P^ +
$5A827999); E := E shr 2 or E shl 30; Inc(P);
      Inc(B, (C shl 5 or C shr 27) + (A xor (D and (E xor A))) + P^ +
$5A827999); D := D shr 2 or D shl 30; Inc(P);
      Inc(A, (B shl 5 or B shr 27) + (E xor (C and (D xor E))) + P^ +
$5A827999); C := C shr 2 or C shl 30; Inc(P);
    end;
  for I := 0 to 3 do
    begin
      Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + P^ + $6ED9EBA1); B
:= B shr 2 or B shl 30; Inc(P);
      Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + P^ + $6ED9EBA1); A
:= A shr 2 or A shl 30; Inc(P);
      Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + P^ + $6ED9EBA1); E
:= E shr 2 or E shl 30; Inc(P);
      Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + P^ + $6ED9EBA1); D
:= D shr 2 or D shl 30; Inc(P);
      Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + P^ + $6ED9EBA1); C
:= C shr 2 or C shl 30; Inc(P);
    end;
  for I := 0 to 3 do
    begin
      Inc(E, (A shl 5 or A shr 27) + ((B and C) or (D and (B or C))) + P^ +
$8F1BBCDC); B := B shr 2 or B shl 30; Inc(P);
      Inc(D, (E shl 5 or E shr 27) + ((A and B) or (C and (A or B))) + P^ +
$8F1BBCDC); A := A shr 2 or A shl 30; Inc(P);
      Inc(C, (D shl 5 or D shr 27) + ((E and A) or (B and (E or A))) + P^ +
$8F1BBCDC); E := E shr 2 or E shl 30; Inc(P);
      Inc(B, (C shl 5 or C shr 27) + ((D and E) or (A and (D or E))) + P^ +
$8F1BBCDC); D := D shr 2 or D shl 30; Inc(P);
      Inc(A, (B shl 5 or B shr 27) + ((C and D) or (E and (C or D))) + P^ +
$8F1BBCDC); C := C shr 2 or C shl 30; Inc(P);
    end;
  for I := 0 to 3 do
    begin
      Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + P^ + $CA62C1D6); B
:= B shr 2 or B shl 30; Inc(P);
      Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + P^ + $CA62C1D6); A
:= A shr 2 or A shl 30; Inc(P);
      Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + P^ + $CA62C1D6); E
:= E shr 2 or E shl 30; Inc(P);
      Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + P^ + $CA62C1D6); D
:= D shr 2 or D shl 30; Inc(P);
      Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + P^ + $CA62C1D6); C
:= C shr 2 or C shl 30; Inc(P);
    end;
  Inc(Digest.Longs[0], A);
  Inc(Digest.Longs[1], B);
  Inc(Digest.Longs[2], C);
  Inc(Digest.Longs[3], D);
  Inc(Digest.Longs[4], E);
end;
procedure SHA1Buf(var Digest: T160BitDigest; const Buf; const BufSize:
Integer);
var P : PByte;
    I, J : Integer;
begin
  I := BufSize;
  if I <= 0 then
    exit;
  Assert(I mod 64 = 0, 'BufSize must be multiple of 64 bytes');
  P := @Buf;
  for J := 0 to I div 64 - 1 do
    begin
      TransformSHABuffer(Digest, P^, True);
      Inc(P, 64);
    end;
end;
procedure ReverseMem(var Buf; const BufSize: Integer);
var I : Integer;
    P : PByte;
    Q : PByte;
    T : Byte;
begin
  P := @Buf;
  Q := P;
  Inc(Q, BufSize - 1);
  for I := 1 to BufSize div 2 do
    begin
      T := P^;
      P^ := Q^;
      Q^ := T;
      Inc(P);
      Dec(Q);
    end;
end;
procedure StdFinalBuf512(
          const Buf; const BufSize: Integer; const TotalSize: Int64;
          var Buf1, Buf2: T512BitBuf;
          var FinalBufs: Integer;
          const SwapEndian: Boolean);
var P, Q : PByte;
    I : Integer;
    L : Int64;
begin
  Assert(BufSize < 64, 'Final BufSize must be less than 64 bytes');
  Assert(TotalSize >= BufSize, 'TotalSize >= BufSize');
  P := @Buf;
  Q := @Buf1[0];
  if BufSize > 0 then
    begin
      Move(P^, Q^, BufSize);
      Inc(Q, BufSize);
    end;
  Q^ := $80;
  Inc(Q);
  L := Int64(TotalSize * 8);
  if SwapEndian then
    ReverseMem(L, 8);
  if BufSize + 1 > 64 - Sizeof(Int64) then
    begin
      FillChar(Q^, 64 - BufSize - 1, #0);
      Q := @Buf2[0];
      FillChar(Q^, 64 - Sizeof(Int64), #0);
      Inc(Q, 64 - Sizeof(Int64));
      PInt64(Q)^ := L;
      FinalBufs := 2;
    end
  else
    begin
      I := 64 - Sizeof(Int64) - BufSize - 1;
      FillChar(Q^, I, #0);
      Inc(Q, I);
      PInt64(Q)^ := L;
      FinalBufs := 1;
    end;
end;
procedure SwapEndianBuf(var Buf; const Count: Integer);
var P : PLongWord;
    I : Integer;
begin
  P := @Buf;
  for I := 1 to Count do
    begin
      P^ := SwapEndian(P^);
      Inc(P);
    end;
end;
procedure SecureClear(var Buf; const BufSize: Integer);
begin
  if BufSize <= 0 then
    exit;
  FillChar(Buf, BufSize, #$00);
end;
procedure SecureClear512(var Buf: T512BitBuf);
begin
  SecureClear(Buf, SizeOf(Buf));
end;
procedure SHA1FinalBuf(var Digest: T160BitDigest; const Buf; const BufSize:
Integer; const TotalSize: Int64);
var B1, B2 : T512BitBuf;
    C : Integer;
begin
  StdFinalBuf512(Buf, BufSize, TotalSize, B1, B2, C, True);
  TransformSHABuffer(Digest, B1, True);
  if C > 1 then
    TransformSHABuffer(Digest, B2, True);
  SwapEndianBuf(Digest, Sizeof(Digest) div Sizeof(LongWord));
  SecureClear512(B1);
  if C > 1 then
    SecureClear512(B2);
end;
function CalcSHA1(const Buf; const BufSize: Integer): T160BitDigest;
var I, J : Integer;
    P    : PByte;
begin
  SHA1InitDigest(Result);
  P := @Buf;
  if BufSize <= 0 then
    I := 0 else
    I := BufSize;
  J := (I div 64) * 64;
  if J > 0 then
    begin
      SHA1Buf(Result, P^, J);
      Inc(P, J);
      Dec(I, J);
    end;
  SHA1FinalBuf(Result, P^, I, BufSize);
end;
procedure HMAC_KeyBlock512(const Key; const KeySize: Integer; var Buf:
T512BitBuf);
var P : PAnsiChar;
begin
  Assert(KeySize <= 64);
  P := @Buf;
  if KeySize > 0 then
    begin
      Move(Key, P^, KeySize);
      Inc(P, KeySize);
    end;
  FillChar(P^, 64 - KeySize, #0);
end;
procedure XORBlock512(var Buf: T512BitBuf; const XOR8: Byte);
var I : Integer;
begin
  for I := 0 to SizeOf(Buf) - 1 do
    Buf[I] := Buf[I] xor XOR8;
end;
procedure HMAC_SHA1Init(const Key: Pointer; const KeySize: Integer; var
Digest: T160BitDigest; var K: T512BitBuf);
var D : T160BitDigest;
    S : T512BitBuf;
begin
  SHA1InitDigest(Digest);
  if KeySize > 64 then
    begin
      D := CalcSHA1(Key^, KeySize);
      HMAC_KeyBlock512(D, Sizeof(D), K);
    end else
    HMAC_KeyBlock512(Key^, KeySize, K);
  Move(K, S, SizeOf(K));
  XORBlock512(S, $36);
  TransformSHABuffer(Digest, S, True);
  SecureClear512(S);
end;
procedure HMAC_SHA1Buf(var Digest: T160BitDigest; const Buf; const BufSize:
Integer);
begin
  SHA1Buf(Digest, Buf, BufSize);
end;
procedure HMAC_SHA1FinalBuf(const K: T512BitBuf; var Digest: T160BitDigest;
const Buf; const BufSize: Integer; const TotalSize: Int64);
var
  FinBuf : packed record
    K : T512BitBuf;
    D : T160BitDigest;
  end;
begin
  SHA1FinalBuf(Digest, Buf, BufSize, TotalSize + 64);
  Move(K, FinBuf.K, SizeOf(K));
  XORBlock512(FinBuf.K, $5C);
  Move(Digest, FinBuf.D, SizeOf(Digest));
  Digest := CalcSHA1(FinBuf, SizeOf(FinBuf));
  SecureClear(FinBuf, SizeOf(FinBuf));
end;
function CalcHMAC_SHA1(const Key: Pointer; const KeySize: Integer; const
Buf; const BufSize: Integer): T160BitDigest;
var I, J : Integer;
    P    : PByte;
    K    : T512BitBuf;
begin
  HMAC_SHA1Init(Key, KeySize, Result, K);
  P := @Buf;
  if BufSize <= 0 then
    I := 0 else
    I := BufSize;
  J := (I div 64) * 64;
  if J > 0 then
    begin
      HMAC_SHA1Buf(Result, P^, J);
      Inc(P, J);
      Dec(I, J);
    end;
  HMAC_SHA1FinalBuf(K, Result, P^, I, BufSize);
  SecureClear512(K);
end;
function CalcHMAC_SHA1(const Key: AnsiString; const Buf; const BufSize:
Integer): T160BitDigest;
begin
  Result := CalcHMAC_SHA1(Pointer(Key), Length(Key), Buf, BufSize);
end;
function CalcHMAC_SHA1(const Key, Buf: AnsiString): T160BitDigest;
begin
  Result := CalcHMAC_SHA1(Key, Pointer(Buf)^, Length(Buf));
end;
procedure DigestToHexBuf(const Digest; const Size: Integer; const Buf);
const s_HexDigitsLower : String[16] = '0123456789abcdef';
var I : Integer;
    P : PAnsiChar;
    Q : PByte;
begin
  P := @Buf;;
  Assert(Assigned(P));
  Q := @Digest;
  Assert(Assigned(Q));
  for I := 0 to Size - 1 do
    begin
      P^ := s_HexDigitsLower[Q^ shr 4 + 1];
      Inc(P);
      P^ := s_HexDigitsLower[Q^ and 15 + 1];
      Inc(P);
      Inc(Q);
    end;
end;
function DigestToHex(const Digest; const Size: Integer): AnsiString;
begin
  SetLength(Result, Size * 2);
  DigestToHexBuf(Digest, Size, Pointer(Result)^);
end;
function SHA1DigestToHex(const Digest: T160BitDigest): AnsiString;
begin
  Result := DigestToHex(Digest, Sizeof(Digest));
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit1.Text := SHA1DigestToHex(CalcHMAC_SHA1('secret',
    'The quick brown fox jumped over the lazy dog.'));  //
5d4db2701c7b07de0e23db3e4f22e88bc1a31a49
end;
end.
Silvio Clécio My public projects - github.com/silvioprog

Reply by email

Tomas Hajny
to silvioprog: 2013/3/23 Tomas Hajny Yes, the "sha1" unit, but how to do it? I was seeing a function in…
silvioprog wrote 18 lines
2013/3/23 Tomas Hajny > On Sat, March 23, 2013 06:28, silvioprog wrote: > > Hi, > > > How to get HMAC_SHA1 using native functions of FPC? > > > > HMAC_SHA1: > > > http://en.wikipedia.org/wiki/Hash-based_message_authentication_code#Examples_of_HMAC_.28MD5.2C_SHA1.2C_SHA256.29 > > Doesn't package hash (included with FPC by default for all targets) > cover > your needs? Yes, the "sha1" unit, but how to do it? I was seeing a function in PHP, but I couldn't port it to the Free Pascal.

Have you also checked the included examples (in particular sha1test.pp)? I haven't used it myself (I had no such need), but it looks quite straightforward to me.

Tomas

Reply by email

silvioprog
to Tomas Hajny

Eureka!

After spending all day working on it, I finally did it! The pseudo steps are here:
http://en.wikipedia.org/wiki/Hash-based_message_authentication_code

And, this is the final code (please improves it please):

uses
  SHA1;
function SHA1Raw(const ABuffer; const ABufferLength: PtrUInt): string;
var
  I: Byte;
  VBytes : TBytes;
  VDigest: TSHA1Digest;
  VContext: TSHA1Context;
begin
  Result := '';
  SHA1Init(VContext);
  SHA1Update(VContext, ABuffer, ABufferLength);
  SHA1Final(VContext, VDigest);
  SetLength(VBytes, 20);
  Move(VDigest, VBytes[0], 20);
  for I := 0 to 19 do
    Result := Result + Char(VBytes[I]);
end;
function HMACSHA1(const AKey, AMessage: string): string;
const
  BLOCK_SIZE = 64;
var
  I: Byte;
  VKey: string;
  VLenght: PtrUInt;
  VOPadStr, VIPadStr: string;
  VOPad, VIPad: array[1..BLOCK_SIZE] of Byte;
begin
  VLenght := Length(AKey);
  if VLenght > BLOCK_SIZE then
  begin
    SetLength(VKey, BLOCK_SIZE);
    FillChar(Pointer(VKey)^, BLOCK_SIZE, #0);
    VKey := SHA1Raw(Pointer(AKey)^, VLenght) + VKey;
  end
  else
  begin
    SetLength(VKey, BLOCK_SIZE - VLenght);
    FillChar(Pointer(VKey)^, BLOCK_SIZE - VLenght, #0);
    VKey := AKey + VKey;
  end;
  FillChar(VOPad, BLOCK_SIZE, $5c);
  FillChar(VIPad, BLOCK_SIZE, $36);
  for I := 1 to BLOCK_SIZE do
  begin
    VOPad[I] := VOPad[I] xor Byte(VKey[I]);
    VIPad[I] := VIPad[I] xor Byte(VKey[I]);
  end;
  SetLength(VOPadStr, BLOCK_SIZE);
  Move(VOPad, Pointer(VOPadStr)^, BLOCK_SIZE);
  SetLength(VIPadStr, BLOCK_SIZE);
  Move(VIPad, Pointer(VIPadStr)^, BLOCK_SIZE);
  VIPadStr := VIPadStr + AMessage;
  Result := SHA1Print(SHA1String(VOPadStr +
    SHA1Raw(Pointer(VIPadStr)^, Length(VIPadStr))));
end;

Usage:

WriteLn(HMACSHA1('key', 'The quick brown fox jumped over the lazy dog.')).

Result: 0b7252985d63555b31db4755f37efe218c509711 (same result in PHP, JS and Phyton! ;) )

So, can you add this code (I'll make HMACMD5 too) in FCL hashes? (>fpc\VER\source\packages\hash\src)

Thank you very much buddies! :)

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

silvioprog
to silvioprog

Oops...

2013/3/24 silvioprog

[...] Result: 0b7252985d63555b31db4755f37efe218c509711 (same result in PHP, JS and Phyton! ;) )

... Result *in my PC*: 0b7252985d63555b31db4755f37efe218c509711

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

David Butler
to silvioprog: Eureka! After spending all day working on it, I finally did it! The pseudo steps are here:

congrats on re-inventing the wheel. all those string allocations/de-allocations could make it slow.

silvioprog wrote 87 lines
Eureka! After spending all day working on it, I finally did it! The pseudo steps are here: http://en.wikipedia.org/wiki/Hash-based_message_authentication_code And, this is the final code (please improves it please): uses SHA1; function SHA1Raw(const ABuffer; const ABufferLength: PtrUInt): string; var I: Byte; VBytes : TBytes; VDigest: TSHA1Digest; VContext: TSHA1Context; begin Result := ''; SHA1Init(VContext); SHA1Update(VContext, ABuffer, ABufferLength); SHA1Final(VContext, VDigest); SetLength(VBytes, 20); Move(VDigest, VBytes[0], 20); for I := 0 to 19 do Result := Result + Char(VBytes[I]); end; function HMACSHA1(const AKey, AMessage: string): string; const BLOCK_SIZE = 64; var I: Byte; VKey: string; VLenght: PtrUInt; VOPadStr, VIPadStr: string; VOPad, VIPad: array[1..BLOCK_SIZE] of Byte; begin VLenght := Length(AKey); if VLenght > BLOCK_SIZE then begin SetLength(VKey, BLOCK_SIZE); FillChar(Pointer(VKey)^, BLOCK_SIZE, #0); VKey := SHA1Raw(Pointer(AKey)^, VLenght) + VKey; end else begin SetLength(VKey, BLOCK_SIZE - VLenght); FillChar(Pointer(VKey)^, BLOCK_SIZE - VLenght, #0); VKey := AKey + VKey; end; FillChar(VOPad, BLOCK_SIZE, $5c); FillChar(VIPad, BLOCK_SIZE, $36); for I := 1 to BLOCK_SIZE do begin VOPad[I] := VOPad[I] xor Byte(VKey[I]); VIPad[I] := VIPad[I] xor Byte(VKey[I]); end; SetLength(VOPadStr, BLOCK_SIZE); Move(VOPad, Pointer(VOPadStr)^, BLOCK_SIZE); SetLength(VIPadStr, BLOCK_SIZE); Move(VIPad, Pointer(VIPadStr)^, BLOCK_SIZE); VIPadStr := VIPadStr + AMessage; Result := SHA1Print(SHA1String(VOPadStr + SHA1Raw(Pointer(VIPadStr)^, Length(VIPadStr)))); end; Usage: WriteLn(HMACSHA1('key', 'The quick brown fox jumped over the lazy dog.')). Result: 0b7252985d63555b31db4755f37efe218c509711 (same result in PHP, JS and Phyton! ;) ) So, can you add this code (I'll make HMACMD5 too) in FCL hashes? (>fpc\VER\source\packages\hash\src) Thank you very much buddies! :) -- Silvio Clécio My public projects - github.com/silvioprog _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

silvioprog
to David Butler

2013/3/24 David Butler

congrats on re-inventing the wheel. all those string allocations/de-allocations could make it slow.

OK, thank you, and what do you suggest to improve this code? Depend on a huge library of third parties and not simply use native code in FCL?

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

silvioprog
to silvioprog

A small improvement:

uses
  SHA1;
function SHA1Raw(const ABuffer; const ABufferLength: PtrUInt): string;
var
  I: Byte;
  VBytes : TBytes;
  VDigest: TSHA1Digest;
  VContext: TSHA1Context;
begin
  Result := '';
  SHA1Init(VContext);
  SHA1Update(VContext, ABuffer, ABufferLength);
  SHA1Final(VContext, VDigest);
  SetLength(VBytes, 20);
  Move(VDigest, VBytes[0], 20);
  for I := 0 to 19 do
    Result := Result + Char(VBytes[I]);
end;
function HMACSHA1(const AKey, AMessage: string): string;
const
  BLOCK_SIZE = 64;
var
  I: Byte;
  VKey: string;
  VLenght: PtrUInt;
  VOPad, VIPad: string;
begin
  VLenght := Length(AKey);
  if VLenght > BLOCK_SIZE then
  begin
    SetLength(VKey, BLOCK_SIZE);
    FillChar(Pointer(VKey)^, BLOCK_SIZE, #0);
    VKey := SHA1Raw(Pointer(AKey)^, VLenght) + VKey;
  end
  else
  begin
    SetLength(VKey, BLOCK_SIZE - VLenght);
    FillChar(Pointer(VKey)^, BLOCK_SIZE - VLenght, #0);
    VKey := AKey + VKey;
  end;
  SetLength(VOPad, BLOCK_SIZE);
  FillChar(Pointer(VOPad)^, BLOCK_SIZE, $5c);
  SetLength(VIPad, BLOCK_SIZE);
  FillChar(Pointer(VIPad)^, BLOCK_SIZE, $36);
  for I := 1 to BLOCK_SIZE do
  begin
    VOPad[I] := Char(Byte(VOPad[I]) xor Byte(VKey[I]));
    VIPad[I] := Char(Byte(VIPad[I]) xor Byte(VKey[I]));
  end;
  VIPad := VIPad + AMessage;
  Result := SHA1Print(SHA1String(VOPad + SHA1Raw(Pointer(VIPad)^,
Length(VIPad))));
end;
Silvio Clécio My public projects - github.com/silvioprog

Reply by email

silvioprog
to silvioprog

My function is more fast that cHash (
http://fundementals.sourceforge.net/dl.html). The comparison result is:

HMAC: 00:00:01:689 cHash: 00:00:02:038

My final unit is:

http://pastebin.com/4484g9i8

The code used in comparison:

uses
  HMAC, cHash;
procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  b, e: TDateTime;
  x: string;
begin
  b := now;
  for i := 0 to 300000 do
    x := HMACSHA1('secret', 'The quick brown fox jumped over the lazy
dog.');
  e := now;
  Edit1.Text := 'HMAC: ' + FormatDateTime('hh:nn:ss:zzz', b - e);
  b := now;
  for i := 0 to 300000 do
    x := SHA1DigestToHex(CalcHMAC_SHA1('secret', 'The quick brown fox
jumped over the lazy dog.'));
  e := now;
  Edit1.Text := Edit1.Text + ' cHash: ' + FormatDateTime('hh:nn:ss:zzz', b
- e);
end;

I reinvented the wheel, but I can run faster now. :)

Thanks guys!

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

silvioprog
to silvioprog

I changed it to:

http://pastebin.com/mxeWtncP

And now:

cHash: 00:00:02:188 HMAC: 00:00:00:966

2013/3/24 silvioprog

Show quoted text 39 lines
My function is more fast that cHash ( http://fundementals.sourceforge.net/dl.html). The comparison result is: HMAC: 00:00:01:689 cHash: 00:00:02:038 My final unit is: http://pastebin.com/4484g9i8 The code used in comparison: uses HMAC, cHash; procedure TForm1.Button1Click(Sender: TObject); var i: Integer; b, e: TDateTime; x: string; begin b := now; for i := 0 to 300000 do x := HMACSHA1('secret', 'The quick brown fox jumped over the lazy dog.'); e := now; Edit1.Text := 'HMAC: ' + FormatDateTime('hh:nn:ss:zzz', b - e); b := now; for i := 0 to 300000 do x := SHA1DigestToHex(CalcHMAC_SHA1('secret', 'The quick brown fox jumped over the lazy dog.')); e := now; Edit1.Text := Edit1.Text + ' cHash: ' + FormatDateTime('hh:nn:ss:zzz', b - e); end; I reinvented the wheel, but I can run faster now. :) Thanks guys!
Silvio Clécio My public projects - github.com/silvioprog

Reply by email

Sven Barth
to silvioprog: My function is more fast that cHash ( http://fundementals.sourceforge.net/dl.html). The…
silvioprog wrote 8 lines
My function is more fast that cHash (http://fundementals.sourceforge.net/dl.html). The comparison result is: HMAC: 00:00:01:689 cHash: 00:00:02:038 My final unit is: http://pastebin.com/4484g9i8

Could you maybe run your unit through some test vectors if you haven't done already? E.g. these: http://tools.ietf.org/html/rfc4231

If that works satisfactory you could create a bug report and we could include it in the hash package.

Regards,
Sven

Reply by email

Sven Barth
to Sven Barth
Sven Barth wrote 12 lines
On 24.03.2013 16:59, silvioprog wrote: > My function is more fast that cHash > (http://fundementals.sourceforge.net/dl.html). The comparison result is: > > HMAC: 00:00:01:689 cHash: 00:00:02:038 > > My final unit is: > > http://pastebin.com/4484g9i8 Could you maybe run your unit through some test vectors if you haven't done already? E.g. these: http://tools.ietf.org/html/rfc4231

Oops. Wrong link. I meant this one: http://tools.ietf.org/html/rfc2202 (contains also test vectors for HMAC-MD5).

If that works satisfactory you could create a bug report and we could include it in the hash package.

Regards,
Sven

Reply by email

silvioprog
to Sven Barth: Could you maybe run your unit through some test vectors if you haven't done already? E.g.…

2013/3/24 Sven Barth

Show quoted text 21 lines
On 24.03.2013 16:59, silvioprog wrote: > My function is more fast that cHash > (http://fundementals.**sourceforge.net/dl.html<http://fundementals.sourceforge.net/dl.html>). > The comparison result is: > > HMAC: 00:00:01:689 cHash: 00:00:02:038 > > My final unit is: > > http://pastebin.com/4484g9i8 > Could you maybe run your unit through some test vectors if you haven't done already? E.g. these: http://tools.ietf.org/html/**rfc4231<http://tools.ietf.org/html/rfc4231> If that works satisfactory you could create a bug report and we could include it in the hash package. Regards, Sven

Yes. I'll try to implement it now! :)

For SHA1 this is the final implementation: http://pastebin.com/t4e3tvXa

Now I'll implement it for MD5 conforming http://tools.ietf.org/html/rfc2202, create some samples showing HMACMD5 and HMACSHA1 and finally create a bug report.

Thank you very much Sven! :)

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

Sven Barth
to silvioprog
silvioprog wrote 38 lines
2013/3/24 Sven Barth < > On 24.03.2013 16:59, silvioprog wrote: My function is more fast that cHash (http://fundementals.__sourceforge.net/dl.html <http://fundementals.sourceforge.net/dl.html>). The comparison result is: HMAC: 00:00:01:689 cHash: 00:00:02:038 My final unit is: http://pastebin.com/4484g9i8 Could you maybe run your unit through some test vectors if you haven't done already? E.g. these: http://tools.ietf.org/html/__rfc4231 <http://tools.ietf.org/html/rfc4231> If that works satisfactory you could create a bug report and we could include it in the hash package. Regards, Sven Yes. I'll try to implement it now! :) For SHA1 this is the final implementation: http://pastebin.com/t4e3tvXa Now I'll implement it for MD5 conforming http://tools.ietf.org/html/rfc2202, create some samples showing HMACMD5 and HMACSHA1 and finally create a bug report. Thank you very much Sven! :)

Some comments:
- Maybe you should have HMACSHA1 return a TSHA1Digest; if the user wants a String she can use SHA1Print herself (and HMACMD5 should consequently return a TMD5Digest) [Note: this will work, because the digest always has a fixed length for MD5 and SHA1 and this is also true for HMAC as you can see in the test vectors in RFC2202)
- I'm not that happy with SHA1Raw and the constants being exported in the interface...

Regards,
Sven

Reply by email

silvioprog
to Sven Barth

2013/3/24 Sven Barth

Show quoted text 55 lines
On 24.03.2013 19:35, silvioprog wrote: > 2013/3/24 Sven Barth < > < >> > > > On 24.03.2013 16:59, silvioprog wrote: > > My function is more fast that cHash > (http://fundementals.__sourcef**orge.net/dl.html<http://sourceforge.net/dl.html> > <http://fundementals.**sourceforge.net/dl.html<http://fundementals.sourceforge.net/dl.html>>). > The comparison > > result is: > > HMAC: 00:00:01:689 cHash: 00:00:02:038 > > My final unit is: > > http://pastebin.com/4484g9i8 > > > Could you maybe run your unit through some test vectors if you > haven't done already? E.g. these: > http://tools.ietf.org/html/__**rfc4231<http://tools.ietf.org/html/__rfc4231> > > <http://tools.ietf.org/html/**rfc4231<http://tools.ietf.org/html/rfc4231> > > > > If that works satisfactory you could create a bug report and we > could include it in the hash package. > > Regards, > Sven > > > Yes. I'll try to implement it now! :) > > For SHA1 this is the final implementation: http://pastebin.com/t4e3tvXa > > Now I'll implement it for MD5 conforming > http://tools.ietf.org/html/**rfc2202 <http://tools.ietf.org/html/rfc2202>, > create some samples showing HMACMD5 > and HMACSHA1 and finally create a bug report. > > Thank you very much Sven! :) > Some comments: - Maybe you should have HMACSHA1 return a TSHA1Digest; if the user wants a String she can use SHA1Print herself (and HMACMD5 should consequently return a TMD5Digest) [Note: this will work, because the digest always has a fixed length for MD5 and SHA1 and this is also true for HMAC as you can see in the test vectors in RFC2202)

Hm... You are right. Those looking for more speed might prefer TSHA1Digest. I'll use TSHA1Digest instead string.

So, I'm tested the test cases and all worked fine, ex (test 2):

=====

test_case = 2
key = "Jefe"
key_len = 4
data = "what do ya want for nothing?"
data_len = 28
digest = 0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79

=====

  with TFileStream.Create('test.txt', fmCreate) do
  try
    X := HMACSHA1('Jefe', 'what do ya want for nothing?');
    Write(Pointer(X)^, Length(X));
  finally
    Free;
  end;

Content in test.txt: effcdf6ae5eb2fa2d27416d5f184df9c259a7c79. Perfect! :-*

- I'm not that happy with SHA1Raw and the constants being exported in the

interface...

:/ I also think not. I'll remove it from the interface.

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

Sven Barth
to silvioprog
silvioprog wrote 67 lines
2013/3/24 Sven Barth < > On 24.03.2013 19:35, silvioprog wrote: 2013/3/24 Sven Barth < < >> On 24.03.2013 16:59, silvioprog wrote: My function is more fast that cHash (http://fundementals.__sourcef__orge.net/dl.html <http://sourceforge.net/dl.html> <http://fundementals.__sourceforge.net/dl.html <http://fundementals.sourceforge.net/dl.html>>). The comparison result is: HMAC: 00:00:01:689 cHash: 00:00:02:038 My final unit is: http://pastebin.com/4484g9i8 Could you maybe run your unit through some test vectors if you haven't done already? E.g. these: http://tools.ietf.org/html/____rfc4231 <http://tools.ietf.org/html/__rfc4231> <http://tools.ietf.org/html/__rfc4231 <http://tools.ietf.org/html/rfc4231>> If that works satisfactory you could create a bug report and we could include it in the hash package. Regards, Sven Yes. I'll try to implement it now! :) For SHA1 this is the final implementation: http://pastebin.com/t4e3tvXa Now I'll implement it for MD5 conforming http://tools.ietf.org/html/__rfc2202 <http://tools.ietf.org/html/rfc2202>, create some samples showing HMACMD5 and HMACSHA1 and finally create a bug report. Thank you very much Sven! :) Some comments: - Maybe you should have HMACSHA1 return a TSHA1Digest; if the user wants a String she can use SHA1Print herself (and HMACMD5 should consequently return a TMD5Digest) [Note: this will work, because the digest always has a fixed length for MD5 and SHA1 and this is also true for HMAC as you can see in the test vectors in RFC2202) Hm... You are right. Those looking for more speed might prefer TSHA1Digest. I'll use TSHA1Digest instead string.

Thank you.

Show quoted text 5 lines
- I'm not that happy with SHA1Raw and the constants being exported in the interface... :/ I also think not. I'll remove it from the interface.

Thank you as well :)

Regards,
Sven

Reply by email

Lukas Gebauer
to silvioprog: I could be wrong, but I think that Synapse function have a bug. See: Using PHP: <?php…
Show quoted text 6 lines
Using Synapse: uses synacode; begin Write(HMAC_SHA1('The quick brown fox jumped over the lazy dog.', 'secret'); end. Result: ]M?p { ? #?>O"?c I

...because you must convert binary string into hexadecimal string, if you wish. Use:

write(StrToHex(HMAC_SHA1('The quick brown fox jumped over the lazy
dog.', 'secret')));
Lukas Gebauer. http://synapse.ararat.cz/ - Ararat Synapse - TCP/IP Lib. http://geoget.ararat.cz/ - Geocaching solution

Reply by email

silvioprog
to Lukas Gebauer

2013/3/25 Lukas Gebauer

Show quoted text 18 lines
> Using Synapse: > uses > synacode; > begin > Write(HMAC_SHA1('The quick brown fox jumped over the lazy dog.', > 'secret'); end. Result: ]M?p { ? #?>O"?c I ...because you must convert binary string into hexadecimal string, if you wish. Use: write(StrToHex(HMAC_SHA1('The quick brown fox jumped over the lazy dog.', 'secret'))); -- Lukas Gebauer. http://synapse.ararat.cz/ - Ararat Synapse - TCP/IP Lib. http://geoget.ararat.cz/ - Geocaching solution

Hello Lukas, thank you very much for the information friend. :)

I've a friend who uses Synapse with Delphi and I'll indicate this routine! ;)

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

silvioprog
to Sven Barth: Could you maybe run your unit through some test vectors if you haven't done already? E.g.…

2013/3/24 Sven Barth

Show quoted text 21 lines
On 24.03.2013 16:59, silvioprog wrote: > My function is more fast that cHash > (http://fundementals.**sourceforge.net/dl.html<http://fundementals.sourceforge.net/dl.html>). > The comparison result is: > > HMAC: 00:00:01:689 cHash: 00:00:02:038 > > My final unit is: > > http://pastebin.com/4484g9i8 > Could you maybe run your unit through some test vectors if you haven't done already? E.g. these: http://tools.ietf.org/html/**rfc4231<http://tools.ietf.org/html/rfc4231> If that works satisfactory you could create a bug report and we could include it in the hash package. Regards, Sven

Done.

http://bugs.freepascal.org/view.php?id=24136

The patch includes source, examples and test cases (7 for MD5 and 7 for SHA1).

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

Anthony Walter
to silvioprog: How to get HMAC_SHA1 using native functions of FPC? HMAC_SHA1:…

I use OpenSSL for this stuff, which can be compiled directly into your project.

{$ifdef windows}
// optionally link library into the project
{$define static}
{$endif}
{$ifdef static}
  {$define libssl := external}
  {$define libeay := external}
{$else}
  {$ifdef unix}
  {$define libssl := external 'libssl.so'}
  {$define libeay := external 'libssl.so'}
  {$else}
  {$define libssl := external 'libssl32.dll'}
    {$define libeay := external 'libeay32.dll'}
  {$endif}
{$endif}
function SSL_library_init: Integer; cdecl; libssl;
procedure SSL_load_error_strings; cdecl; libssl;
function SSLv23_client_method: TSSLMethod; cdecl; libssl;
function SSL_CTX_new(method: TSSLMethod): TSSLCtx; cdecl; libssl;
procedure SSL_CTX_free(context: TSSLCtx); cdecl; libssl;
function SSL_new(context: TSSLCtx): TSSL; cdecl; libssl;
function SSL_shutdown(ssl: TSSL): LongInt; cdecl; libssl;
procedure SSL_free(ssl: TSSL); cdecl; libssl;
function SSL_set_fd(ssl: TSSL; socket: LongInt): LongBool; cdecl; libssl;
function SSL_connect(ssl: TSSL): LongBool; cdecl; libssl;
function SSL_write(ssl: TSSL; buffer: Pointer; size: LongWord): LongInt;
cdecl; libssl;
function SSL_read(ssl: TSSL; buffer: Pointer; size: LongWord): LongInt;
cdecl; libssl;
function SSL_get_error(ssl: TSSL; ret_code: Integer): Integer; cdecl;
libssl;

{ Hashing routines }

function MD5_Init(out context: TMD5Ctx): LongBool; cdecl; libeay;
function MD5_Update(var context: TMD5Ctx; data: Pointer; size: Cardinal):
LongBool; cdecl; libeay;
function MD5_Final(out digest: TMD5Digest; var context: TMD5Ctx): LongBool;
cdecl; libeay;
function SHA1_Init(out context: TSHA1Ctx): LongBool; cdecl; libeay;
function SHA1_Update(var context: TSHA1Ctx; data: Pointer; size: Cardinal):
LongBool; cdecl; libeay;
function SHA1_Final(out digest: TSHA1Digest; var context: TSHA1Ctx):
LongBool; cdecl; libeay;
function SHA256_Init(out context: TSHA256Ctx): LongBool; cdecl; libeay;
function SHA256_Update(var context: TSHA256Ctx; data: Pointer; size:
Cardinal): LongBool; cdecl; libeay;
function SHA256_Final(out digest: TSHA256Digest; var context: TSHA256Ctx):
LongBool; cdecl; libeay;
function SHA512_Init(out context: TSHA512Ctx): LongBool; cdecl; libeay;
function SHA512_Update(var context: TSHA512Ctx; data: Pointer; size:
Cardinal): LongBool; cdecl; libeay;
function SHA512_Final(out digest: TSHA512Digest; var context: TSHA512Ctx):
LongBool; cdecl; libeay;
function EVP_md5: TEVPMethod; cdecl; libeay;
function EVP_sha1: TEVPMethod; cdecl; libeay;
function EVP_sha256: TEVPMethod; cdecl; libeay;
function EVP_sha512: TEVPMethod; cdecl; libeay;
procedure HMAC_CTX_init(out context: THMACCtx); cdecl; libeay;
procedure HMAC_CTX_cleanup(var context: THMACCtx); cdecl; libeay;
function HMAC_Init_ex(var context: THMACCtx; key: Pointer; size: Cardinal;
method: TEVPMethod; engine: Pointer): LongBool; cdecl; libeay;
function HMAC_Update(var context: THMACCtx; data: Pointer; size: Cardinal):
LongBool; cdecl; libeay;
function HMAC_Final(var context: THMACCtx; digest: Pointer; var digestSize:
LongWord): LongBool; cdecl; libeay;
implementation
{$ifdef static}
{$linklib libssl.a}
{$linklib libcrypto.a}
{$endif}

Reply by email

silvioprog
to Anthony Walter

2013/3/26 Anthony Walter

Show quoted text 80 lines
I use OpenSSL for this stuff, which can be compiled directly into your project. {$ifdef windows} // optionally link library into the project {$define static} {$endif} {$ifdef static} {$define libssl := external} {$define libeay := external} {$else} {$ifdef unix} {$define libssl := external 'libssl.so'} {$define libeay := external 'libssl.so'} {$else} {$define libssl := external 'libssl32.dll'} {$define libeay := external 'libeay32.dll'} {$endif} {$endif} function SSL_library_init: Integer; cdecl; libssl; procedure SSL_load_error_strings; cdecl; libssl; function SSLv23_client_method: TSSLMethod; cdecl; libssl; function SSL_CTX_new(method: TSSLMethod): TSSLCtx; cdecl; libssl; procedure SSL_CTX_free(context: TSSLCtx); cdecl; libssl; function SSL_new(context: TSSLCtx): TSSL; cdecl; libssl; function SSL_shutdown(ssl: TSSL): LongInt; cdecl; libssl; procedure SSL_free(ssl: TSSL); cdecl; libssl; function SSL_set_fd(ssl: TSSL; socket: LongInt): LongBool; cdecl; libssl; function SSL_connect(ssl: TSSL): LongBool; cdecl; libssl; function SSL_write(ssl: TSSL; buffer: Pointer; size: LongWord): LongInt; cdecl; libssl; function SSL_read(ssl: TSSL; buffer: Pointer; size: LongWord): LongInt; cdecl; libssl; function SSL_get_error(ssl: TSSL; ret_code: Integer): Integer; cdecl; libssl; { Hashing routines } function MD5_Init(out context: TMD5Ctx): LongBool; cdecl; libeay; function MD5_Update(var context: TMD5Ctx; data: Pointer; size: Cardinal): LongBool; cdecl; libeay; function MD5_Final(out digest: TMD5Digest; var context: TMD5Ctx): LongBool; cdecl; libeay; function SHA1_Init(out context: TSHA1Ctx): LongBool; cdecl; libeay; function SHA1_Update(var context: TSHA1Ctx; data: Pointer; size: Cardinal): LongBool; cdecl; libeay; function SHA1_Final(out digest: TSHA1Digest; var context: TSHA1Ctx): LongBool; cdecl; libeay; function SHA256_Init(out context: TSHA256Ctx): LongBool; cdecl; libeay; function SHA256_Update(var context: TSHA256Ctx; data: Pointer; size: Cardinal): LongBool; cdecl; libeay; function SHA256_Final(out digest: TSHA256Digest; var context: TSHA256Ctx): LongBool; cdecl; libeay; function SHA512_Init(out context: TSHA512Ctx): LongBool; cdecl; libeay; function SHA512_Update(var context: TSHA512Ctx; data: Pointer; size: Cardinal): LongBool; cdecl; libeay; function SHA512_Final(out digest: TSHA512Digest; var context: TSHA512Ctx): LongBool; cdecl; libeay; function EVP_md5: TEVPMethod; cdecl; libeay; function EVP_sha1: TEVPMethod; cdecl; libeay; function EVP_sha256: TEVPMethod; cdecl; libeay; function EVP_sha512: TEVPMethod; cdecl; libeay; procedure HMAC_CTX_init(out context: THMACCtx); cdecl; libeay; procedure HMAC_CTX_cleanup(var context: THMACCtx); cdecl; libeay; function HMAC_Init_ex(var context: THMACCtx; key: Pointer; size: Cardinal; method: TEVPMethod; engine: Pointer): LongBool; cdecl; libeay; function HMAC_Update(var context: THMACCtx; data: Pointer; size: Cardinal): LongBool; cdecl; libeay; function HMAC_Final(var context: THMACCtx; digest: Pointer; var digestSize: LongWord): LongBool; cdecl; libeay; implementation {$ifdef static} {$linklib libssl.a} {$linklib libcrypto.a} {$endif}

Nice.

But there situations that the user does not have the OpenSSL lib.

The routines I sent does not depend on external libs.

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

Anthony Walter
to silvioprog
silvioprog wrote 10 lines
Nice. But there situations that the user does not have the OpenSSL lib. The routines I sent does not depend on external libs. -- Silvio Clécio My public projects - github.com/silvioprog

It's possible to build static lib files for Win 32 and 64 on Linux.

... download the sources from here http://www.openssl.org/source/ then ...

sudo apt-get install mingw-w64

... goto the OpenSSL source directory and ...

CROSS_COMPILE="i686-w64-mingw32-" ./Configure mingw64 no-asm shared make
CROSS_COMPILE="x86_64-w64-mingw32-" ./Configure mingw64 no-asm shared make

... and copy libcrypto.a and libssl.a to a FPC lib path ...

Now you can compile for Win 32/64 using OpenSSL static lib files.

Reply by email

silvioprog
to Anthony Walter

2013/3/26 Anthony Walter

Show quoted text 31 lines
On Mon, Mar 25, 2013 at 11:24 PM, silvioprog wrote: > Nice. > > But there situations that the user does not have the OpenSSL lib. > > The routines I sent does not depend on external libs. > > -- > Silvio Clécio > My public projects - github.com/silvioprog > It's possible to build static lib files for Win 32 and 64 on Linux. ... download the sources from here http://www.openssl.org/source/ then ... sudo apt-get install mingw-w64 ... goto the OpenSSL source directory and ... CROSS_COMPILE="i686-w64-mingw32-" ./Configure mingw64 no-asm shared make CROSS_COMPILE="x86_64-w64-mingw32-" ./Configure mingw64 no-asm shared make ... and copy libcrypto.a and libssl.a to a FPC lib path ... Now you can compile for Win 32/64 using OpenSSL static lib files.

o.o'

Don't know why so much work if you can use it directly from the FCL.

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

Anthony Walter
to silvioprog
silvioprog wrote
Don't know why so much work if you can use it directly from the FCL.

Because...

OpenSSL is quite robust, well documented. tested, and proven OpenSSL provides a full compilement of cryptography and hashing functions On Linux/OSX you can link to external shared object files, which further reduces project build size and system resources

Side benefit: OpenSSL also provides a simple secure socket implementation, which many times pairs nicely along with SHA/HMAC

Reply by email

silvioprog
to Anthony Walter

2013/3/26 Anthony Walter

Show quoted text 15 lines
On Tue, Mar 26, 2013 at 12:23 AM, silvioprog wrote: > Don't know why so much work if you can use it directly from the FCL. > Because... OpenSSL is quite robust, well documented. tested, and proven OpenSSL provides a full compilement of cryptography and hashing functions On Linux/OSX you can link to external shared object files, which further reduces project build size and system resources Side benefit: OpenSSL also provides a simple secure socket implementation, which many times pairs nicely along with SHA/HMAC

I don't know if you noticed, but I sent the ALL test cases required by the RFC 2202 (http://tools.ietf.org/html/rfc2202), i.e., it's enough to check whether the algorithm it's well implemented or not.

I'll await the answer of the staff of Core, because for me the final answer is theirs.

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

Anthony Walter
to silvioprog
silvioprog wrote 15 lines
I don't know if you noticed, but I sent the ALL test cases required by the RFC 2202 (http://tools.ietf.org/html/rfc2202), i.e., it's enough to check whether the algorithm it's well implemented or not. I'll await the answer of the staff of Core, because for me the final answer is theirs. -- Silvio Clécio My public projects - github.com/silvioprog _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

I wasn't asking you to stop your work, rather I was attempting to share insights and my opinions with the group. My point in the previous message was that many times it make sense to reuse something which works, and possibly part of the operating system, rather than recreating that which already exists.

Reply by email

silvioprog
to Anthony Walter

2013/3/26 Anthony Walter

Show quoted text 20 lines
On Tue, Mar 26, 2013 at 1:20 AM, silvioprog wrote: > I don't know if you noticed, but I sent the ALL test cases required by > the RFC 2202 (http://tools.ietf.org/html/rfc2202), i.e., it's enough to > check whether the algorithm it's well implemented or not. > > I'll await the answer of the staff of Core, because for me the final > answer is theirs. > > -- > Silvio Clécio > My public projects - github.com/silvioprog > I wasn't asking you to stop your work, rather I was attempting to share insights and my opinions with the group. My point in the previous message was that many times it make sense to reuse something which works, and possibly part of the operating system, rather than recreating that which already exists.

OK, sorry.

I'm rooting for them implement it direct in FCL. The routines in hmac.pp will fall like a glove.

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

Sven Barth
to Anthony Walter: I wasn't asking you to stop your work, rather I was attempting to share insights and my…
Anthony Walter wrote 27 lines
On Tue, Mar 26, 2013 at 1:20 AM, silvioprog < > wrote: I don't know if you noticed, but I sent the ALL test cases required by the RFC 2202 (http://tools.ietf.org/html/rfc2202), i.e., it's enough to check whether the algorithm it's well implemented or not. I'll await the answer of the staff of Core, because for me the final answer is theirs. -- Silvio Clécio My public projects - github.com/silvioprog <http://github.com/silvioprog> _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal I wasn't asking you to stop your work, rather I was attempting to share insights and my opinions with the group. My point in the previous message was that many times it make sense to reuse something which works, and possibly part of the operating system, rather than recreating that which already exists.

We already have a "hash" package and I'm all for improving/extending it. This can prove especially useful for platforms where OpenSSL is not supported (think the embedded targets or similar here). Also I'm a big fan of "as less non-Pascal dependencies as possible" :)

Regards,
Sven

Reply by email

Marcos Douglas
to Anthony Walter: It's possible to build static lib files for Win 32 and 64 on Linux. ... download the…
Anthony Walter wrote 30 lines
On Mon, Mar 25, 2013 at 11:24 PM, silvioprog wrote: > > Nice. > > But there situations that the user does not have the OpenSSL lib. > > The routines I sent does not depend on external libs. > > -- > Silvio Clécio > My public projects - github.com/silvioprog It's possible to build static lib files for Win 32 and 64 on Linux. ... download the sources from here http://www.openssl.org/source/ then ... sudo apt-get install mingw-w64 ... goto the OpenSSL source directory and ... CROSS_COMPILE="i686-w64-mingw32-" ./Configure mingw64 no-asm shared make CROSS_COMPILE="x86_64-w64-mingw32-" ./Configure mingw64 no-asm shared make ... and copy libcrypto.a and libssl.a to a FPC lib path ... Now you can compile for Win 32/64 using OpenSSL static lib files.

Hi,
Is possible to make that only using Windows for any lib?

Best regards,
Marcos Douglas

Reply by email

Anthony Walter
to Marcos Douglas
Marcos Douglas wrote 5 lines
Hi, Is possible to make that only using Windows for any lib? Best regards, Marcos Douglas

Marcos,

Are you asking, "Is it possible to build any static lib for Windows and link it to a free pascal project"?

No, not all the time. Libraries may depend on systems function on one platform which are not available on another.

But, many times you can if the library can compile with mingw64. When this is the case you build a C project using mingw64, copy the lib files to a directory free pascal is using (see environment settings in lazarus), list the functions in a unit, then put {$linklib youlibname.a} in the implementation section. You may need a few {$ifdef}s for your different platforms.

The benefit of this is that you can easily incorporate (much more easily rewriting) *complex* functionality into your free pascal projects knowing what you are reusing is probably faster, has more features, is more robust, and better tested than a implementation of X that someone reinvented again for free pascal.

Sometimes though you might be are better off using dynamic linking (so, dll on windows) if you know the OS is going to provide features. Examples are msxml.dll vs libxml2.so, gdiplus.dll vs libcario.so, ect. Of course in these cases what probably you need to do is write some lite wrappers, since the apis vary in form (but not function). In those cases I typically use interfaces...

IXmlDocument, IXmlNode // for pasring or building Xml ICanvas, IBrush // for drawing

and then

function CreateXmlDocument: IXmlDocument; {$fidef}s
function CreateCanvas: ICanvas; {$fidef}s

Reply by email

Ludo Brands
to Sven Barth: We already have a "hash" package and I'm all for improving/extending it. This can prove…
Sven Barth wrote 12 lines
Am 26.03.2013 06:53, schrieb Anthony Walter: > I wasn't asking you to stop your work, rather I was attempting to > share insights and my opinions with the group. My point in the > previous message was that many times it make sense to reuse something > which works, and possibly part of the operating system, rather than > recreating that which already exists. We already have a "hash" package and I'm all for improving/extending it. This can prove especially useful for platforms where OpenSSL is not supported (think the embedded targets or similar here). Also I'm a big fan of "as less non-Pascal dependencies as possible" :)

Another advantage of OpenSSL is performance. Especially on x64 where OpenSSL is an order of magnitude faster than fe. the synapse sha1 implementation. It uses assembly to optimize code. I doubt that will ever be done in a FPC library.

Ludo

Reply by email

Marcos Douglas
to Anthony Walter: Are you asking, "Is it possible to build any static lib for Windows and link it to a free…
Anthony Walter wrote 13 lines
On Tue, Mar 26, 2013 at 5:57 AM, Marcos Douglas wrote: > > Hi, > Is possible to make that only using Windows for any lib? > > Best regards, > Marcos Douglas Marcos, Are you asking, "Is it possible to build any static lib for Windows and link it to a free pascal project"?

Yes, that's it. Thank you.

Show quoted text 9 lines
No, not all the time. Libraries may depend on systems function on one platform which are not available on another. But, many times you can if the library can compile with mingw64. When this is the case you build a C project using mingw64, copy the lib files to a directory free pascal is using (see environment settings in lazarus), list the functions in a unit, then put {$linklib youlibname.a} in the implementation section. You may need a few {$ifdef}s for your different platforms.

I had seen this $linklib but I did not know what it was for.

Show quoted text 20 lines
The benefit of this is that you can easily incorporate (much more easily rewriting) *complex* functionality into your free pascal projects knowing what you are reusing is probably faster, has more features, is more robust, and better tested than a implementation of X that someone reinvented again for free pascal. Sometimes though you might be are better off using dynamic linking (so, dll on windows) if you know the OS is going to provide features. Examples are msxml.dll vs libxml2.so, gdiplus.dll vs libcario.so, ect. Of course in these cases what probably you need to do is write some lite wrappers, since the apis vary in form (but not function). In those cases I typically use interfaces... IXmlDocument, IXmlNode // for pasring or building Xml ICanvas, IBrush // for drawing and then function CreateXmlDocument: IXmlDocument; {$fidef}s function CreateCanvas: ICanvas; {$fidef}s

Good ideas. Thank you for share.

Marcos Douglas

Reply by email

silvioprog
to Sven Barth: We already have a "hash" package and I'm all for improving/extending it. This can prove…

2013/3/26 Sven Barth

Show quoted text 34 lines
Am 26.03.2013 06:53, schrieb Anthony Walter: On Tue, Mar 26, 2013 at 1:20 AM, silvioprog wrote: > I don't know if you noticed, but I sent the ALL test cases required by > the RFC 2202 (http://tools.ietf.org/html/rfc2202), i.e., it's enough to > check whether the algorithm it's well implemented or not. > > I'll await the answer of the staff of Core, because for me the final > answer is theirs. > > -- > Silvio Clécio > My public projects - github.com/silvioprog > > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal > I wasn't asking you to stop your work, rather I was attempting to share insights and my opinions with the group. My point in the previous message was that many times it make sense to reuse something which works, and possibly part of the operating system, rather than recreating that which already exists. We already have a "hash" package and I'm all for improving/extending it. This can prove especially useful for platforms where OpenSSL is not supported (think the embedded targets or similar here). Also I'm a big fan of "as less non-Pascal dependencies as possible" :) Regards, Sven

+1.

And I'm sure the hmac is fast as anything else out there who write, even using libs maked in C/C+. :)

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

Sven Barth
to Ludo Brands: Another advantage of OpenSSL is performance. Especially on x64 where OpenSSL is an order…
"Ludo Brands" wrote 19 lines
On 03/26/2013 10:40 AM, Sven Barth wrote: > Am 26.03.2013 06:53, schrieb Anthony Walter: >> I wasn't asking you to stop your work, rather I was attempting to >> share insights and my opinions with the group. My point in the >> previous message was that many times it make sense to reuse something >> which works, and possibly part of the operating system, rather than >> recreating that which already exists. > We already have a "hash" package and I'm all for improving/extending it. > This can prove especially useful for platforms where OpenSSL is not > supported (think the embedded targets or similar here). Also I'm a big > fan of "as less non-Pascal dependencies as possible" :) > Another advantage of OpenSSL is performance. Especially on x64 where OpenSSL is an order of magnitude faster than fe. the synapse sha1 implementation. It uses assembly to optimize code. I doubt that will ever be done in a FPC library.

If someone provides a patch to additionally add assembly versions to cryptographic algorithms I doubt that we'll turn them down...

Regards,
Sven

Reply by email

Noah Silva
to Anthony Walter: Because... OpenSSL is quite robust, well documented. tested, and proven OpenSSL provides…

Hi,

Actually I think on OS X and Linux it makes sense to depend on OpenSSL, but not for the reasons you mentioned so much as one more: Security. If you are using doing encryption, then it's better to use a library that is updated more often for bug fixes, and to have the updates be applied to your program automatically. If you static-link it in, it will never be updated until you update it and ship a new version of your program and everyone installs it. If you dynamically link to it, then then the operating system updates it, you get the updates "for free".

After bad past experiences with VB and OCX files that broke all the time, and Java (enough said), I vastly prefer to use Pascal code in most cases and have everything linked static (less moving parts = less to break) - but there can be exceptions. (I use SQLite a lot, which isn't included by default in Windows). For HMAC only though I just use Synapse.

Thank you,
Noah Silva

2013/3/26 Anthony Walter

Show quoted text 19 lines
On Tue, Mar 26, 2013 at 12:23 AM, silvioprog wrote: > Don't know why so much work if you can use it directly from the FCL. > Because... OpenSSL is quite robust, well documented. tested, and proven OpenSSL provides a full compilement of cryptography and hashing functions On Linux/OSX you can link to external shared object files, which further reduces project build size and system resources Side benefit: OpenSSL also provides a simple secure socket implementation, which many times pairs nicely along with SHA/HMAC _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

silvioprog
to Noah Silva

2013/4/2 Noah Silva

Show quoted text 20 lines
Hi, Actually I think on OS X and Linux it makes sense to depend on OpenSSL, but not for the reasons you mentioned so much as one more: Security. If you are using doing encryption, then it's better to use a library that is updated more often for bug fixes, and to have the updates be applied to your program automatically. If you static-link it in, it will never be updated until you update it and ship a new version of your program and everyone installs it. If you dynamically link to it, then then the operating system updates it, you get the updates "for free". After bad past experiences with VB and OCX files that broke all the time, and Java (enough said), I vastly prefer to use Pascal code in most cases and have everything linked static (less moving parts = less to break) - but there can be exceptions. (I use SQLite a lot, which isn't included by default in Windows). For HMAC only though I just use Synapse. Thank you, Noah Silva

Well, who wants to link and configure an entire DLL to use only a single function, so be it. Who wants to use and configure an entire lib (Synapse, DCPcrypt etc) to use only a single function, so be it. But nothing prevents that it being implemented directly in the FCL, quick to declare/use.

Sorry, but I'll stop commenting in this topic. Now I feel like a dog trying to chasing its own tail (
http://stream1.gifsoup.com/webroot/animatedgifs6/2077970_o.gif). :p

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

Reinier Olislagers
to Noah Silva: Actually I think on OS X and Linux it makes sense to depend on OpenSSL, but not for the…
Noah Silva wrote
Actually I think on OS X and Linux it makes sense to depend on OpenSSL, but not for the reasons you mentioned so much as one more: Security.

That's probably why the previous poster wrote robust etc. Sounds like security attributes to me.

Show quoted text 7 lines
If you are using doing encryption, then it's better to use a library that is updated more often for bug fixes, and to have the updates be applied to your program automatically. If you static-link it in, it will never be updated until you update it and ship a new version of your program and everyone installs it. If you dynamically link to it, then then the operating system updates it, you get the updates "for free".

If you feel so strongly about it, why not submit a patch that uses OpenSSL on platforms that are sure to have it and use Silvio's native code for others?

Reply by email

Noah Silva
to Reinier Olislagers

Hi Reinier,

2013/4/2 Reinier Olislagers

Show quoted text 10 lines
... be updated until you update it and ship a new version of your program > and everyone installs it. If you dynamically link to it, then then the > operating system updates it, you get the updates "for free". If you feel so strongly about it, why not submit a patch that uses OpenSSL on platforms that are sure to have it and use Silvio's native code for others?

Haha I was just mentioning one positive benefit. Also, I am pretty sure Synapse can use the OpenSSL DLLs.

I am much more likely to submit some patches to the OS X GUI for Lazarus that I have been fixing in the last week or so. We'll see.

Thank you,
Noah Silva

p.s.: I don't see a big deal in pulling in something like Synapse so long as it compiles easily for your platform. You don't have to use all the units, and the linker shouldn't even include all of the code from the units you do use. If you only use one function that is mostly contained (like HMAC), then it shouldn't add much to your program's size in the scheme of things. I don't like when people use things that aren't really needed mainly because you have to then download them and pray they compile on your setup. (And in some cases, recompile Lazarus!). For more common things that "just work", I have no issue.

Reply by email

Mark Morgan Lloyd
to Reinier Olislagers: That's probably why the previous poster wrote robust etc. Sounds like security attributes…
Reinier Olislagers wrote 14 lines
On 2-4-2013 5:13, Noah Silva wrote: > Actually I think on OS X and Linux it makes sense to depend on OpenSSL, > but not for the reasons you mentioned so much as one more: Security. That's probably why the previous poster wrote robust etc. Sounds like security attributes to me. > If > you are using doing encryption, then it's better to use a library that > is updated more often for bug fixes, and to have the updates be applied > to your program automatically. If you static-link it in, it will never > be updated until you update it and ship a new version of your program > and everyone installs it. If you dynamically link to it, then then the > operating system updates it, you get the updates "for free".

Depends. If you're using (say) a hash function to store a token in lieu of a password then the important thing is that this behaves consistently across platforms and program versions. If an external library eliminated a potential security flaw (the most common case being when null text was processed) that might be significant in the case of key scheduling for data transfer over an insecure channel, but not for purely local storage.

As usual, there's little substitute for the original programmer knowing what he's doing, and for him documenting what he's done so that maintainers know what sort of external event can cause an issue.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Reinier Olislagers
to Noah Silva: 2013/4/2 Reinier Olislagers Haha I was just mentioning one positive benefit. Also, I am…
Noah Silva wrote 9 lines
2013/4/2 Reinier Olislagers < > If you feel so strongly about it, why not submit a patch that uses OpenSSL on platforms that are sure to have it and use Silvio's native code for others? Haha I was just mentioning one positive benefit. Also, I am pretty sure Synapse can use the OpenSSL DLLs.

Yep.

I am much more likely to submit some patches to the OS X GUI for Lazarus that I have been fixing in the last week or so. We'll see.

That does seem like a more worthwhile area, yes....

Thank you, Noah Silva

No worries,
Reinier

Show quoted text 9 lines
p.s.: I don't see a big deal in pulling in something like Synapse so long as it compiles easily for your platform. You don't have to use all the units, and the linker shouldn't even include all of the code from the units you do use. If you only use one function that is mostly contained (like HMAC), then it shouldn't add much to your program's size in the scheme of things. I don't like when people use things that aren't really needed mainly because you have to then download them and pray they compile on your setup. (And in some cases, recompile Lazarus!). For more common things that "just work", I have no issue.

Agreed - Synapse is nicely self-contained and modular.

Reply by email

Reinier Olislagers
to Mark Morgan Lloyd: Depends. If you're using (say) a hash function to store a token in lieu of a password…
Mark Morgan Lloyd wrote 8 lines
Reinier Olislagers wrote: > On 2-4-2013 5:13, Noah Silva wrote: Depends. If you're using (say) a hash function to store a token in lieu of a password then the important thing is that this behaves consistently across platforms and program versions. If an external library eliminated a potential security flaw (the most common case being when null text was processed) that might be significant in the case of key scheduling for data transfer over an insecure channel, but not for purely local storage.

Well, yes. But you can hardly limit use of the function to local storage only.

As usual, there's little substitute for the original programmer knowing what he's doing, and for him documenting what he's done so that maintainers know what sort of external event can cause an issue.

... and prove it works/interoperates by including a test set, as I think Silvio has done.

Reply by email

Victor Campillo
to silvioprog: 2013/3/24 Sven Barth Done. http://bugs.freepascal.org/view.php?id=24136 The patch…
silvioprog wrote 10 lines
Done. http://bugs.freepascal.org/view.php?id=24136 The patch includes source, examples and test cases (7 for MD5 and 7 for SHA1). -- Silvio Clécio My public projects - github.com/silvioprog <http://github.com/silvioprog>

Hi

Thank very much Silvio for share this, today I was looking for a code for HMACMD5 and I don't wanna use a big library like Dcpcrypt or Synapse or Opennssl, when I develop for embedded platform I try to avoid dependencies as much as possible.

Best regards.

Reply by email