1 unit SHA5_256;
2
3 {SHA512/256 - 256 bit Secure Hash Function}
4
5
6 interface
7
8 (*************************************************************************
9
10 DESCRIPTION : SHA512/256 - 256 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 : - Latest specification of Secure Hash Standard:
21 http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
22 - Test vectors and intermediate values:
23 http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf
24
25 Version Date Author Modification
26 ------- -------- ------- ------------------------------------------
27 0.10 14.02.11 W.Ehrhardt Initial BP version using SHA384 layout
28 0.11 15.02.11 we Updated OID
29 0.12 16.02.11 we function pSHA5_256_Desc
30 0.13 08.03.12 we RegisterHash(_SHA512_256...)
31 0.14 08.03.12 we Changed HName to 'SHA512/256', updates URLs
32 0.15 08.03.12 we removed pSHA5_256_Desc
33 0.16 16.08.15 we Removed $ifdef DLL / stdcall
34 0.17 15.05.17 we adjust OID to new MaxOIDLen
35 0.18 29.11.17 we SHA5_256File - fname: string
36
37 **************************************************************************)
38
39 (*-------------------------------------------------------------------------
40 (C) Copyright 2011-2017 Wolfgang Ehrhardt
41
42 This software is provided 'as-is', without any express or implied warranty.
43 In no event will the authors be held liable for any damages arising from
44 the use of this software.
45
46 Permission is granted to anyone to use this software for any purpose,
47 including commercial applications, and to alter it and redistribute it
48 freely, subject to the following restrictions:
49
50 1. The origin of this software must not be misrepresented; you must not
51 claim that you wrote the original software. If you use this software in
52 a product, an acknowledgment in the product documentation would be
53 appreciated but is not required.
54
55 2. Altered source versions must be plainly marked as such, and must not be
56 misrepresented as being the original software.
57
58 3. This notice may not be removed or altered from any source distribution.
59 ----------------------------------------------------------------------------*)
60
61
62 {$i STD.INC}
63
64 uses
65 BTypes,Hash,SHA512;
66
67
68 procedure SHA5_256Init(var Context: THashContext);
69 {-initialize context}
70
71 procedure SHA5_256Update(var Context: THashContext; Msg: pointer; Len: word);
72 {-update context with Msg data}
73
74 procedure SHA5_256UpdateXL(var Context: THashContext; Msg: pointer; Len: longint);
75 {-update context with Msg data}
76
77 procedure SHA5_256Final(var Context: THashContext; var Digest: TSHA5_256Digest);
78 {-finalize SHA512/256 calculation, clear context}
79
80 procedure SHA5_256FinalEx(var Context: THashContext; var Digest: THashDigest);
81 {-finalize SHA512/256 calculation, clear context}
82
83 procedure SHA5_256FinalBitsEx(var Context: THashContext; var Digest: THashDigest; BData: byte; bitlen: integer);
84 {-finalize SHA512/256 calculation with bitlen bits from BData (big-endian), clear context}
85
86 procedure SHA5_256FinalBits(var Context: THashContext; var Digest: TSHA5_256Digest; BData: byte; bitlen: integer);
87 {-finalize SHA512/256 calculation with bitlen bits from BData (big-endian), clear context}
88
SHA5_256SelfTestnull89 function SHA5_256SelfTest: boolean;
90 {-self test for string from SHA512/256 document}
91
92 procedure SHA5_256Full(var Digest: TSHA5_256Digest; Msg: pointer; Len: word);
93 {-SHA512/256 of Msg with init/update/final}
94
95 procedure SHA5_256FullXL(var Digest: TSHA5_256Digest; Msg: pointer; Len: longint);
96 {-SHA512/256 of Msg with init/update/final}
97
98 procedure SHA5_256File({$ifdef CONST} const {$endif} fname: string;
99 var Digest: TSHA5_256Digest; var buf; bsize: word; var Err: word);
100 {-SHA512/256 of file, buf: buffer with at least bsize bytes}
101
102
103 implementation
104
105
106 const
107 SHA5_256_BlockLen = 128;
108
109 {http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html}
110 {2.16.840.1.101.3.4.2.6}
111 {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) SHA512/256(6)}
112
113 const
114 SHA5_256_OID : TOID_Vec = (2,16,840,1,101,3,4,2,6,-1,-1); {Len=9}
115
116
117 {$ifndef VER5X}
118 const
119 SHA5_256_Desc: THashDesc = (
120 HSig : C_HashSig;
121 HDSize : sizeof(THashDesc);
122 HDVersion : C_HashVers;
123 HBlockLen : SHA5_256_BlockLen;
124 HDigestlen: sizeof(TSHA5_256Digest);
125 {$ifdef FPC_ProcVar}
126 HInit : @SHA5_256Init;
127 HFinal : @SHA5_256FinalEx;
128 HUpdateXL : @SHA5_256UpdateXL;
129 {$else}
130 HInit : SHA5_256Init;
131 HFinal : SHA5_256FinalEx;
132 HUpdateXL : SHA5_256UpdateXL;
133 {$endif}
134 HAlgNum : longint(_SHA512_256);
135 HName : 'SHA512/256';
136 HPtrOID : @SHA5_256_OID;
137 HLenOID : 9;
138 HFill : 0;
139 {$ifdef FPC_ProcVar}
140 HFinalBit : @SHA5_256FinalBitsEx;
141 {$else}
142 HFinalBit : SHA5_256FinalBitsEx;
143 {$endif}
144 HReserved : (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
145 );
146 {$else}
147 var
148 SHA5_256_Desc: THashDesc;
149 {$endif}
150
151
152 {$ifdef BIT16}
153 {$F-}
154 {$endif}
155
156
157 {---------------------------------------------------------------------------}
158 procedure SHA5_256Init(var Context: THashContext);
159 {-initialize context}
160 {$ifdef StrictLong}
161 {$warnings off}
162 {$R-} {avoid D9 errors!}
163 {$endif}
164 const
165 SIV: THashState = ($fc2bf72c,$22312194,$c84c64c2,$9f555fa3,
166 $6f53b151,$2393b86b,$5940eabd,$96387719,
167 $a88effe3,$96283ee2,$53863992,$be5e1e25,
168 $2c85b8aa,$2b0199fc,$81c52ca2,$0eb72ddc);
169 {$ifdef StrictLong}
170 {$warnings on}
171 {$ifdef RangeChecks_on}
172 {$R+}
173 {$endif}
174 {$endif}
175 begin
176 {Clear context}
177 fillchar(Context,sizeof(Context),0);
178 Context.Hash := SIV;
179 end;
180
181
182 {---------------------------------------------------------------------------}
183 procedure SHA5_256UpdateXL(var Context: THashContext; Msg: pointer; Len: longint);
184 {-update context with Msg data}
185 begin
186 SHA512UpdateXL(THashContext(Context), Msg, Len);
187 end;
188
189
190 {---------------------------------------------------------------------------}
191 procedure SHA5_256Update(var Context: THashContext; Msg: pointer; Len: word);
192 {-update context with Msg data}
193 begin
194 SHA512UpdateXL(THashContext(Context), Msg, Len);
195 end;
196
197
198 {---------------------------------------------------------------------------}
199 procedure SHA5_256FinalBitsEx(var Context: THashContext; var Digest: THashDigest; BData: byte; bitlen: integer);
200 {-finalize SHA512/256 calculation with bitlen bits from BData (big-endian), clear context}
201 begin
202 SHA512FinalBitsEx(Context, Digest, BData, bitlen);
203 end;
204
205
206 {---------------------------------------------------------------------------}
207 procedure SHA5_256FinalBits(var Context: THashContext; var Digest: TSHA5_256Digest; BData: byte; bitlen: integer);
208 {-finalize SHA512/256 calculation with bitlen bits from BData (big-endian), clear context}
209 var
210 tmp: THashDigest;
211 begin
212 SHA512FinalBitsEx(Context, tmp, BData, bitlen);
213 move(tmp, Digest, sizeof(Digest));
214 end;
215
216
217 {---------------------------------------------------------------------------}
218 procedure SHA5_256FinalEx(var Context: THashContext; var Digest: THashDigest);
219 {-finalize SHA512/256 calculation, clear context}
220 begin
221 SHA512FinalBitsEx(Context, Digest,0,0);
222 end;
223
224
225 {---------------------------------------------------------------------------}
226 procedure SHA5_256Final(var Context: THashContext; var Digest: TSHA5_256Digest);
227 {-finalize SHA512/256 calculation, clear context}
228 var
229 tmp: THashDigest;
230 begin
231 SHA512FinalBitsEx(Context, tmp, 0, 0);
232 move(tmp, Digest, sizeof(Digest));
233 end;
234
235
236 {---------------------------------------------------------------------------}
SHA5_256SelfTestnull237 function SHA5_256SelfTest: boolean;
238 {-self test for string from SHA512/256 document}
239 const
240 s1: string[3] = 'abc';
241 s2: string[112] = 'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn'
242 +'hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu';
243
244 D1: TSHA5_256Digest = ($53,$04,$8e,$26,$81,$94,$1e,$f9,
245 $9b,$2e,$29,$b7,$6b,$4c,$7d,$ab,
246 $e4,$c2,$d0,$c6,$34,$fc,$6d,$46,
247 $e0,$e2,$f1,$31,$07,$e7,$af,$23);
248
249 D2: TSHA5_256Digest = ($39,$28,$e1,$84,$fb,$86,$90,$f8,
250 $40,$da,$39,$88,$12,$1d,$31,$be,
251 $65,$cb,$9d,$3e,$f8,$3e,$e6,$14,
252 $6f,$ea,$c8,$61,$e1,$9b,$56,$3a);
253
254 var
255 Context: THashContext;
256 Digest : TSHA5_256Digest;
257
SingleTestnull258 function SingleTest(s: Str127; TDig: TSHA5_256Digest): boolean;
259 {-do a single test, const not allowed for VER<7}
260 { Two sub tests: 1. whole string, 2. one update per char}
261 var
262 i: integer;
263 begin
264 SingleTest := false;
265 {1. Hash complete string}
266 SHA5_256Full(Digest, @s[1],length(s));
267 {Compare with known value}
268 if not HashSameDigest(@SHA5_256_Desc, PHashDigest(@Digest), PHashDigest(@TDig)) then exit;
269 {2. one update call for all chars}
270 SHA5_256Init(Context);
271 for i:=1 to length(s) do SHA5_256Update(Context,@s[i],1);
272 SHA5_256Final(Context,Digest);
273 {Compare with known value}
274 if not HashSameDigest(@SHA5_256_Desc, PHashDigest(@Digest), PHashDigest(@TDig)) then exit;
275 SingleTest := true;
276 end;
277
278 begin
279 {strings from SHA512/256 document}
280 SHA5_256SelfTest := SingleTest(s1, D1) and SingleTest(s2, D2)
281 end;
282
283
284 {---------------------------------------------------------------------------}
285 procedure SHA5_256FullXL(var Digest: TSHA5_256Digest; Msg: pointer; Len: longint);
286 {-SHA512/256 of Msg with init/update/final}
287 var
288 Context: THashContext;
289 begin
290 SHA5_256Init(Context);
291 SHA5_256UpdateXL(Context, Msg, Len);
292 SHA5_256Final(Context, Digest);
293 end;
294
295
296 {---------------------------------------------------------------------------}
297 procedure SHA5_256Full(var Digest: TSHA5_256Digest; Msg: pointer; Len: word);
298 {-SHA512/256 of Msg with init/update/final}
299 begin
300 SHA5_256FullXL(Digest, Msg, Len);
301 end;
302
303
304 {---------------------------------------------------------------------------}
305 procedure SHA5_256File({$ifdef CONST} const {$endif} fname: string;
306 var Digest: TSHA5_256Digest; var buf; bsize: word; var Err: word);
307 {-SHA512/256 of file, buf: buffer with at least bsize bytes}
308 var
309 tmp: THashDigest;
310 begin
311 HashFile(fname, @SHA5_256_Desc, tmp, buf, bsize, Err);
312 move(tmp, Digest, sizeof(Digest));
313 end;
314
315
316 begin
317 {$ifdef VER5X}
318 fillchar(SHA5_256_Desc, sizeof(SHA5_256_Desc), 0);
319 with SHA5_256_Desc do begin
320 HSig := C_HashSig;
321 HDSize := sizeof(THashDesc);
322 HDVersion := C_HashVers;
323 HBlockLen := SHA5_256_BlockLen;
324 HDigestlen:= sizeof(TSHA5_256Digest);
325 HInit := SHA5_256Init;
326 HFinal := SHA5_256FinalEx;
327 HUpdateXL := SHA5_256UpdateXL;
328 HAlgNum := longint(_SHA512_256);
329 HName := 'SHA512/256';
330 HPtrOID := @SHA5_256_OID;
331 HLenOID := 9;
332 HFinalBit := SHA5_256FinalBitsEx;
333 end;
334 {$endif}
335 RegisterHash(_SHA512_256, @SHA5_256_Desc);
336 end.
337