1 unit SHA3_224;
2 
3 {SHA3-224 - 224 bit Secure Hash Function}
4 
5 
6 interface
7 
8 (*************************************************************************
9 
10  DESCRIPTION     :  SHA3-224 - 224 bit Secure Hash Function
11 
12  REQUIREMENTS    :  TP5-7, D1-D7/D9-D10/D12/D17-D18/D25S, FPC, VP
13 
14  EXTERNAL DATA   :  ---
15 
16  MEMORY USAGE    :  ---
17 
18  DISPLAY MODE    :  ---
19 
20  REFERENCES      :  - FIPS 202 SHA-3 Standard: 'Permutation-Based Hash and
21                       Extendable-Output Functions' available from
22                       http://csrc.nist.gov/publications/PubsFIPS.html or
23                       http://dx.doi.org/10.6028/NIST.FIPS.202 or
24                       http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
25                     - Test vectors and intermediate values:
26                       http://csrc.nist.gov/groups/ST/toolkit/examples.html
27 
28  Version  Date      Author      Modification
29  -------  --------  -------     ------------------------------------------
30  0.10     10.08.15  W.Ehrhardt  Initial BP version using SHA3-256 layout
31  0.11     17.08.15  we          Updated references
32  0.12     15.05.17  we          adjust OID to new MaxOIDLen
33  0.13     29.11.17  we          SHA3_224File - fname: string
34 
35 **************************************************************************)
36 
37 (*-------------------------------------------------------------------------
38  (C) Copyright 2015-2017 Wolfgang Ehrhardt
39 
40  This software is provided 'as-is', without any express or implied warranty.
41  In no event will the authors be held liable for any damages arising from
42  the use of this software.
43 
44  Permission is granted to anyone to use this software for any purpose,
45  including commercial applications, and to alter it and redistribute it
46  freely, subject to the following restrictions:
47 
48  1. The origin of this software must not be misrepresented; you must not
49     claim that you wrote the original software. If you use this software in
50     a product, an acknowledgment in the product documentation would be
51     appreciated but is not required.
52 
53  2. Altered source versions must be plainly marked as such, and must not be
54     misrepresented as being the original software.
55 
56  3. This notice may not be removed or altered from any source distribution.
57 ----------------------------------------------------------------------------*)
58 
59 
60 {$i STD.INC}
61 
62 uses
63   BTypes,Hash,SHA3;
64 
65 
66 procedure SHA3_224Init(var Context: THashContext);
67   {-initialize context}
68 
69 procedure SHA3_224Update(var Context: THashContext; Msg: pointer; Len: word);
70   {-update context with Msg data}
71 
72 procedure SHA3_224UpdateXL(var Context: THashContext; Msg: pointer; Len: longint);
73   {-update context with Msg data}
74 
75 procedure SHA3_224Final(var Context: THashContext; var Digest: TSHA3_224Digest);
76   {-finalize SHA3-224 calculation, clear context}
77 
78 procedure SHA3_224FinalEx(var Context: THashContext; var Digest: THashDigest);
79   {-finalize SHA3-224 calculation, clear context}
80 
81 procedure SHA3_224FinalBitsEx(var Context: THashContext; var Digest: THashDigest; BData: byte; bitlen: integer);
82   {-finalize SHA3-224 calculation with bitlen bits from BData (big-endian), clear context}
83 
84 procedure SHA3_224FinalBits(var Context: THashContext; var Digest: TSHA3_224Digest; BData: byte; bitlen: integer);
85   {-finalize SHA3-224 calculation with bitlen bits from BData (big-endian), clear context}
86 
87 procedure SHA3_224FinalBits_LSB(var Context: THashContext; var Digest: TSHA3_224Digest; BData: byte; bitlen: integer);
88   {-finalize SHA3-224 calculation with bitlen bits from BData (LSB format), clear context}
89 
SHA3_224SelfTestnull90 function  SHA3_224SelfTest: boolean;
91   {-self test for string from SHA3-224 documents}
92 
93 procedure SHA3_224Full(var Digest: TSHA3_224Digest; Msg: pointer; Len: word);
94   {-SHA3-224 of Msg with init/update/final}
95 
96 procedure SHA3_224FullXL(var Digest: TSHA3_224Digest; Msg: pointer; Len: longint);
97   {-SHA3-224 of Msg with init/update/final}
98 
99 procedure SHA3_224File({$ifdef CONST} const {$endif} fname: string;
100                      var Digest: TSHA3_224Digest; var buf; bsize: word; var Err: word);
101   {-SHA3-224 of file, buf: buffer with at least bsize bytes}
102 
103 
104 implementation
105 
106 
107 const
108   SHA3_224_BlockLen = 144;  {Rate / 8, used only for HMAC} {FIPS202, Tab.3}
109 
110 {http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html}
111 {2.16.840.1.101.3.4.2.8}
112 {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) SHA3-224(7)}
113 
114 const
115   SHA3_224_OID : TOID_Vec = (2,16,840,1,101,3,4,2,7,-1,-1); {Len=9}
116 
117 
118 {$ifndef VER5X}
119 const
120   SHA3_224_Desc: THashDesc = (
121                HSig      : C_HashSig;
122                HDSize    : sizeof(THashDesc);
123                HDVersion : C_HashVers;
124                HBlockLen : SHA3_224_BlockLen;
125                HDigestlen: sizeof(TSHA3_224Digest);
126              {$ifdef FPC_ProcVar}
127                HInit     : @SHA3_224Init;
128                HFinal    : @SHA3_224FinalEx;
129                HUpdateXL : @SHA3_224UpdateXL;
130              {$else}
131                HInit     : SHA3_224Init;
132                HFinal    : SHA3_224FinalEx;
133                HUpdateXL : SHA3_224UpdateXL;
134              {$endif}
135                HAlgNum   : longint(_SHA3_224);
136                HName     : 'SHA3-224';
137                HPtrOID   : @SHA3_224_OID;
138                HLenOID   : 9;
139                HFill     : 0;
140              {$ifdef FPC_ProcVar}
141                HFinalBit : @SHA3_224FinalBitsEx;
142              {$else}
143                HFinalBit : SHA3_224FinalBitsEx;
144              {$endif}
145                HReserved : (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
146             );
147 {$else}
148 var
149   SHA3_224_Desc: THashDesc;
150 {$endif}
151 
152 
153 {$ifdef BIT16}
154   {$F-}
155 {$endif}
156 
157 
158 {---------------------------------------------------------------------------}
159 procedure SHA3_224Init(var Context: THashContext);
160   {-initialize context}
161 begin
162   {Clear context}
163   SHA3_LastError := SHA3_Init(TSHA3State(Context),__SHA3_224);
164 end;
165 
166 
167 {---------------------------------------------------------------------------}
168 procedure SHA3_224UpdateXL(var Context: THashContext; Msg: pointer; Len: longint);
169    {-update context with Msg data}
170 begin
171   SHA3_LastError := SHA3_UpdateXL(TSHA3State(Context), Msg, Len);
172 end;
173 
174 
175 {---------------------------------------------------------------------------}
176 procedure SHA3_224Update(var Context: THashContext; Msg: pointer; Len: word);
177    {-update context with Msg data}
178 begin
179   SHA3_LastError := SHA3_UpdateXL(TSHA3State(Context), Msg, Len);
180 end;
181 
182 
183 {---------------------------------------------------------------------------}
184 procedure SHA3_224FinalBitsEx(var Context: THashContext; var Digest: THashDigest; BData: byte; bitlen: integer);
185   {-finalize SHA3-224 calculation with bitlen bits from BData (big-endian), clear context}
186 begin
187   SHA3_LastError := SHA3_FinalBit(TSHA3State(Context), BData, bitlen, @Digest[0], 8*sizeof(Digest));
188 end;
189 
190 
191 {---------------------------------------------------------------------------}
192 procedure SHA3_224FinalBits(var Context: THashContext; var Digest: TSHA3_224Digest; BData: byte; bitlen: integer);
193   {-finalize SHA3-224 calculation with bitlen bits from BData (big-endian), clear context}
194 begin
195   SHA3_LastError := SHA3_FinalBit(TSHA3State(Context), BData, bitlen, @Digest[0], 8*sizeof(Digest));
196 end;
197 
198 
199 {---------------------------------------------------------------------------}
200 procedure SHA3_224FinalBits_LSB(var Context: THashContext; var Digest: TSHA3_224Digest; BData: byte; bitlen: integer);
201   {-finalize SHA3-224 calculation with bitlen bits from BData (LSB format), clear context}
202 begin
203   SHA3_LastError := SHA3_FinalBit_LSB(TSHA3State(Context), BData, bitlen, @Digest[0], 8*sizeof(Digest));
204 end;
205 
206 
207 {---------------------------------------------------------------------------}
208 procedure SHA3_224FinalEx(var Context: THashContext; var Digest: THashDigest);
209   {-finalize SHA3-224 calculation, clear context}
210 begin
211   SHA3_LastError := SHA3_FinalHash(TSHA3State(Context), @Digest[0]);
212 end;
213 
214 
215 {---------------------------------------------------------------------------}
216 procedure SHA3_224Final(var Context: THashContext; var Digest: TSHA3_224Digest);
217   {-finalize SHA3-224 calculation, clear context}
218 begin
219   SHA3_LastError := SHA3_FinalHash(TSHA3State(Context), @Digest[0]);
220 end;
221 
222 
223 {---------------------------------------------------------------------------}
SHA3_224SelfTestnull224 function SHA3_224SelfTest: boolean;
225   {-self test for string from SHA3-224 documents}
226 const
227   Bl1 = 0;
228   dig1: TSHA3_224Digest      = ($6B,$4E,$03,$42,$36,$67,$DB,$B7,$3B,$6E,
229                                 $15,$45,$4F,$0E,$B1,$AB,$D4,$59,$7F,$9A,
230                                 $1B,$07,$8E,$3F,$5B,$5A,$6B,$C7);
231   BL2 = 5;
232   msg2: array[0..0] of byte  = ($13);
233   dig2: TSHA3_224Digest      = ($FF,$BA,$D5,$DA,$96,$BA,$D7,$17,$89,$33,
234                                 $02,$06,$DC,$67,$68,$EC,$AE,$B1,$B3,$2D,
235                                 $CA,$6B,$33,$01,$48,$96,$74,$AB);
236   BL3 = 30;
237   msg3: array[0..3] of byte  = ($53,$58,$7B,$19);
238   dig3: TSHA3_224Digest      = ($D6,$66,$A5,$14,$CC,$9D,$BA,$25,$AC,$1B,
239                                 $A6,$9E,$D3,$93,$04,$60,$DE,$AA,$C9,$85,
240                                 $1B,$5F,$0B,$AA,$B0,$07,$DF,$3B);
241 
242   {https://github.com/gvanas/KeccakCodePackage, SKat len=200}
243   BL4 = 200;
244   msg4: array[0..24] of byte = ($aa,$fd,$c9,$24,$3d,$3d,$4a,$09,
245                                 $65,$58,$a3,$60,$cc,$27,$c8,$d8,
246                                 $62,$f0,$be,$73,$db,$5e,$88,$aa,$55);
247   dig4: TSHA3_224Digest      = ($23,$60,$6d,$06,$fd,$8f,$87,$c2,
248                                 $20,$5a,$bb,$5f,$d0,$4c,$33,$eb,
249                                 $a3,$05,$09,$95,$52,$00,$56,$6a,
250                                 $0f,$77,$2b,$49);
251 var
252   Context: THashContext;
253   Digest : TSHA3_224Digest;
254 
SingleTestnull255   function SingleTest(Msg: pointer; BL: word; TDig: TSHA3_224Digest): boolean;
256   var
257     bytes: word;
258   begin
259     SingleTest := false;
260     SHA3_224Init(Context);
261     if SHA3_LastError<>0 then exit;
262     if BL=0 then SHA3_224Final(Context,Digest)
263     else begin
264       if BL>7 then begin
265         bytes := BL shr 3;
266         SHA3_224Update(Context, Msg, BL shr 3);
267         if SHA3_LastError<>0 then exit;
268         inc(Ptr2Inc(Msg), bytes);
269       end;
270       SHA3_224FinalBits_LSB(Context, Digest, pByte(Msg)^, BL and 7);
271     end;
272     if SHA3_LastError<>0 then exit;
273     SingleTest := HashSameDigest(@SHA3_224_Desc, PHashDigest(@TDig), PHashDigest(@Digest));
274   end;
275 
276 begin
277   SHA3_224SelfTest := SingleTest(nil, BL1, dig1)   and
278                       SingleTest(@msg2, BL2, dig2) and
279                       SingleTest(@msg3, BL3, dig3) and
280                       SingleTest(@msg4, BL4, dig4);
281 end;
282 
283 
284 {---------------------------------------------------------------------------}
285 procedure SHA3_224FullXL(var Digest: TSHA3_224Digest; Msg: pointer; Len: longint);
286   {-SHA3-224 of Msg with init/update/final}
287 var
288   Context: THashContext;
289 begin
290   SHA3_224Init(Context);
291   if SHA3_LastError=0 then SHA3_224UpdateXL(Context, Msg, Len);
292   SHA3_224Final(Context, Digest);
293 end;
294 
295 
296 {---------------------------------------------------------------------------}
297 procedure SHA3_224Full(var Digest: TSHA3_224Digest; Msg: pointer; Len: word);
298   {-SHA3-224 of Msg with init/update/final}
299 begin
300   SHA3_224FullXL(Digest, Msg, Len);
301 end;
302 
303 
304 {---------------------------------------------------------------------------}
305 procedure SHA3_224File({$ifdef CONST} const {$endif} fname: string;
306                      var Digest: TSHA3_224Digest; var buf; bsize: word; var Err: word);
307   {-SHA3-224 of file, buf: buffer with at least bsize bytes}
308 var
309   tmp: THashDigest;
310 begin
311   HashFile(fname, @SHA3_224_Desc, tmp, buf, bsize, Err);
312   move(tmp, Digest, sizeof(Digest));
313 end;
314 
315 
316 begin
317   {$ifdef VER5X}
318     fillchar(SHA3_224_Desc, sizeof(SHA3_224_Desc), 0);
319     with SHA3_224_Desc do begin
320        HSig      := C_HashSig;
321        HDSize    := sizeof(THashDesc);
322        HDVersion := C_HashVers;
323        HBlockLen := SHA3_224_BlockLen;
324        HDigestlen:= sizeof(TSHA3_224Digest);
325        HInit     := SHA3_224Init;
326        HFinal    := SHA3_224FinalEx;
327        HUpdateXL := SHA3_224UpdateXL;
328        HAlgNum   := longint(_SHA3_224);
329        HName     := 'SHA3-224';
330        HPtrOID   := @SHA3_224_OID;
331        HLenOID   := 9;
332        HFinalBit := SHA3_224FinalBitsEx;
333     end;
334   {$endif}
335   RegisterHash(_SHA3_224, @SHA3_224_Desc);
336 end.
337