| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- unit HMAC;
- {General HMAC unit}
- interface
- (*************************************************************************
- DESCRIPTION : General HMAC (hash message authentication) unit
- REQUIREMENTS : TP5-7, D1-D7/D9-D10/D12/D17-D18, FPC, VP
- EXTERNAL DATA : ---
- MEMORY USAGE : ---
- DISPLAY MODE : ---
- REFERENCES : - HMAC: Keyed-Hashing for Message Authentication
- (http://tools.ietf.org/html/rfc2104)
- - The Keyed-Hash Message Authentication Code (HMAC)
- http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf
- - US Secure Hash Algorithms (SHA and HMAC-SHA)
- (http://tools.ietf.org/html/rfc4634)
- REMARKS : Trailing bits in SHA3-LSB format must be converted to MSB
- Version Date Author Modification
- ------- -------- ------- ------------------------------------------
- 0.10 15.01.06 W.Ehrhardt Initial version based on HMACWHIR
- 0.11 07.05.08 we hmac_final_bits
- 0.12 12.11.08 we Uses BTypes, THMAC_string replaced by Str255
- 0.13 25.04.09 we updated RFC URL(s)
- 0.14 08.08.15 we type of hmacbuf changed to THMacBuffer
- 0.15 16.08.15 we Removed $ifdef DLL / stdcall
- **************************************************************************)
- (*-------------------------------------------------------------------------
- (C) Copyright 2006-2015 Wolfgang Ehrhardt
- This software is provided 'as-is', without any express or implied warranty.
- In no event will the authors be held liable for any damages arising from
- the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software in
- a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
- ----------------------------------------------------------------------------*)
- uses
- BTypes,hash;
- type
- THMAC_Context = record
- hashctx: THashContext;
- hmacbuf: THMacBuffer;
- phashd : PHashDesc;
- end;
- procedure hmac_init(var ctx: THMAC_Context; phash: PHashDesc; key: pointer; klen: word);
- {-initialize HMAC context with hash descr phash^ and key}
- procedure hmac_inits(var ctx: THMAC_Context; phash: PHashDesc; skey: Str255);
- {-initialize HMAC context with hash descr phash^ and skey}
- procedure hmac_update(var ctx: THMAC_Context; data: pointer; dlen: word);
- {-HMAC data input, may be called more than once}
- procedure hmac_updateXL(var ctx: THMAC_Context; data: pointer; dlen: longint);
- {-HMAC data input, may be called more than once}
- procedure hmac_final(var ctx: THMAC_Context; var mac: THashDigest);
- {-end data input, calculate HMAC digest}
- procedure hmac_final_bits(var ctx: THMAC_Context; var mac: THashDigest; BData: byte; bitlen: integer);
- {-end data input with bitlen bits (MSB format) from BData, calculate HMAC digest}
- implementation
- {---------------------------------------------------------------------------}
- procedure hmac_init(var ctx: THMAC_Context; phash: PHashDesc; key: pointer; klen: word);
- {-initialize HMAC context with hash descr phash^ and key}
- var
- i,lk,bl: word;
- kb: THashDigest;
- begin
- fillchar(ctx, sizeof(ctx),0);
- if phash<>nil then with ctx do begin
- phashd := phash;
- lk := klen;
- bl := phash^.HBlockLen;
- if lk > bl then begin
- {Hash if key length > block length}
- HashFullXL(phash, kb, key, lk);
- lk := phash^.HDigestLen;
- move(kb, hmacbuf, lk);
- end
- else move(key^, hmacbuf, lk);
- {XOR with ipad}
- for i:=0 to bl-1 do hmacbuf[i] := hmacbuf[i] xor $36;
- {start inner hash}
- phash^.HInit(hashctx);
- phash^.HUpdateXL(hashctx, @hmacbuf, bl);
- end;
- end;
- {---------------------------------------------------------------------------}
- procedure hmac_inits(var ctx: THMAC_Context; phash: PHashDesc; skey: Str255);
- {-initialize HMAC context with hash descr phash^ and skey}
- begin
- if phash<>nil then hmac_init(ctx, phash, @skey[1], length(skey));
- end;
- {---------------------------------------------------------------------------}
- procedure hmac_update(var ctx: THMAC_Context; data: pointer; dlen: word);
- {-HMAC data input, may be called more than once}
- begin
- with ctx do begin
- if phashd<>nil then phashd^.HUpdateXL(hashctx, data, dlen);
- end;
- end;
- {---------------------------------------------------------------------------}
- procedure hmac_updateXL(var ctx: THMAC_Context; data: pointer; dlen: longint);
- {-HMAC data input, may be called more than once}
- begin
- with ctx do begin
- if phashd<>nil then phashd^.HUpdateXL(hashctx, data, dlen);
- end;
- end;
- {---------------------------------------------------------------------------}
- procedure hmac_final(var ctx: THMAC_Context; var mac: THashDigest);
- {-end data input, calculate HMAC digest}
- var
- i: integer;
- bl: word;
- begin
- with ctx do if phashd<>nil then begin
- bl := phashd^.HBlockLen;
- {complete inner hash}
- phashd^.HFinal(hashctx, mac);
- {remove ipad from buf, XOR opad}
- for i:=0 to bl-1 do hmacbuf[i] := hmacbuf[i] xor ($36 xor $5c);
- {outer hash}
- phashd^.HInit(hashctx);
- phashd^.HUpdateXL(hashctx, @hmacbuf, bl);
- phashd^.HUpdateXL(hashctx, @mac, phashd^.HDigestLen);
- phashd^.HFinal(hashctx, mac);
- end;
- end;
- {---------------------------------------------------------------------------}
- procedure hmac_final_bits(var ctx: THMAC_Context; var mac: THashDigest; BData: byte; bitlen: integer);
- {-end data input with bitlen bits (MSB format) from BData, calculate HMAC digest}
- var
- i: integer;
- bl: word;
- begin
- with ctx do if phashd<>nil then begin
- bl := phashd^.HBlockLen;
- {complete inner hash}
- phashd^.HFinalBit(hashctx, mac, BData, bitlen);
- {remove ipad from buf, XOR opad}
- for i:=0 to bl-1 do hmacbuf[i] := hmacbuf[i] xor ($36 xor $5c);
- {outer hash}
- phashd^.HInit(hashctx);
- phashd^.HUpdateXL(hashctx, @hmacbuf, bl);
- phashd^.HUpdateXL(hashctx, @mac, phashd^.HDigestLen);
- phashd^.HFinal(hashctx, mac);
- end;
- end;
- end.
|