annotate gcc/ada/libgnat/g-sechas.adb @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT LIBRARY COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- G N A T . S E C U R E _ H A S H E S --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
kono
parents:
diff changeset
9 -- Copyright (C) 2009-2017, Free Software Foundation, Inc. --
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
kono
parents:
diff changeset
17 -- --
kono
parents:
diff changeset
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
kono
parents:
diff changeset
19 -- additional permissions described in the GCC Runtime Library Exception, --
kono
parents:
diff changeset
20 -- version 3.1, as published by the Free Software Foundation. --
kono
parents:
diff changeset
21 -- --
kono
parents:
diff changeset
22 -- You should have received a copy of the GNU General Public License and --
kono
parents:
diff changeset
23 -- a copy of the GCC Runtime Library Exception along with this program; --
kono
parents:
diff changeset
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
kono
parents:
diff changeset
25 -- <http://www.gnu.org/licenses/>. --
kono
parents:
diff changeset
26 -- --
kono
parents:
diff changeset
27 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
29 -- --
kono
parents:
diff changeset
30 ------------------------------------------------------------------------------
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 with System; use System;
kono
parents:
diff changeset
33 with Interfaces; use Interfaces;
kono
parents:
diff changeset
34
kono
parents:
diff changeset
35 package body GNAT.Secure_Hashes is
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 Hex_Digit : constant array (Stream_Element range 0 .. 15) of Character :=
kono
parents:
diff changeset
38 "0123456789abcdef";
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 type Fill_Buffer_Access is
kono
parents:
diff changeset
41 access procedure
kono
parents:
diff changeset
42 (M : in out Message_State;
kono
parents:
diff changeset
43 S : String;
kono
parents:
diff changeset
44 First : Natural;
kono
parents:
diff changeset
45 Last : out Natural);
kono
parents:
diff changeset
46 -- A procedure to transfer data from S, starting at First, into M's block
kono
parents:
diff changeset
47 -- buffer until either the block buffer is full or all data from S has been
kono
parents:
diff changeset
48 -- consumed.
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 procedure Fill_Buffer_Copy
kono
parents:
diff changeset
51 (M : in out Message_State;
kono
parents:
diff changeset
52 S : String;
kono
parents:
diff changeset
53 First : Natural;
kono
parents:
diff changeset
54 Last : out Natural);
kono
parents:
diff changeset
55 -- Transfer procedure which just copies data from S to M
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 procedure Fill_Buffer_Swap
kono
parents:
diff changeset
58 (M : in out Message_State;
kono
parents:
diff changeset
59 S : String;
kono
parents:
diff changeset
60 First : Natural;
kono
parents:
diff changeset
61 Last : out Natural);
kono
parents:
diff changeset
62 -- Transfer procedure which swaps bytes from S when copying into M. S must
kono
parents:
diff changeset
63 -- have even length. Note that the swapping is performed considering pairs
kono
parents:
diff changeset
64 -- starting at S'First, even if S'First /= First (that is, if
kono
parents:
diff changeset
65 -- First = S'First then the first copied byte is always S (S'First + 1),
kono
parents:
diff changeset
66 -- and if First = S'First + 1 then the first copied byte is always
kono
parents:
diff changeset
67 -- S (S'First).
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 procedure To_String (SEA : Stream_Element_Array; S : out String);
kono
parents:
diff changeset
70 -- Return the hexadecimal representation of SEA
kono
parents:
diff changeset
71
kono
parents:
diff changeset
72 ----------------------
kono
parents:
diff changeset
73 -- Fill_Buffer_Copy --
kono
parents:
diff changeset
74 ----------------------
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 procedure Fill_Buffer_Copy
kono
parents:
diff changeset
77 (M : in out Message_State;
kono
parents:
diff changeset
78 S : String;
kono
parents:
diff changeset
79 First : Natural;
kono
parents:
diff changeset
80 Last : out Natural)
kono
parents:
diff changeset
81 is
kono
parents:
diff changeset
82 Buf_String : String (M.Buffer'Range);
kono
parents:
diff changeset
83 for Buf_String'Address use M.Buffer'Address;
kono
parents:
diff changeset
84 pragma Import (Ada, Buf_String);
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 Length : constant Natural :=
kono
parents:
diff changeset
87 Natural'Min (M.Block_Length - M.Last, S'Last - First + 1);
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 begin
kono
parents:
diff changeset
90 pragma Assert (Length > 0);
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 Buf_String (M.Last + 1 .. M.Last + Length) :=
kono
parents:
diff changeset
93 S (First .. First + Length - 1);
kono
parents:
diff changeset
94 M.Last := M.Last + Length;
kono
parents:
diff changeset
95 Last := First + Length - 1;
kono
parents:
diff changeset
96 end Fill_Buffer_Copy;
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 ----------------------
kono
parents:
diff changeset
99 -- Fill_Buffer_Swap --
kono
parents:
diff changeset
100 ----------------------
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 procedure Fill_Buffer_Swap
kono
parents:
diff changeset
103 (M : in out Message_State;
kono
parents:
diff changeset
104 S : String;
kono
parents:
diff changeset
105 First : Natural;
kono
parents:
diff changeset
106 Last : out Natural)
kono
parents:
diff changeset
107 is
kono
parents:
diff changeset
108 pragma Assert (S'Length mod 2 = 0);
kono
parents:
diff changeset
109 Length : constant Natural :=
kono
parents:
diff changeset
110 Natural'Min (M.Block_Length - M.Last, S'Last - First + 1);
kono
parents:
diff changeset
111 begin
kono
parents:
diff changeset
112 Last := First;
kono
parents:
diff changeset
113 while Last - First < Length loop
kono
parents:
diff changeset
114 M.Buffer (M.Last + 1 + Last - First) :=
kono
parents:
diff changeset
115 (if (Last - S'First) mod 2 = 0
kono
parents:
diff changeset
116 then S (Last + 1)
kono
parents:
diff changeset
117 else S (Last - 1));
kono
parents:
diff changeset
118 Last := Last + 1;
kono
parents:
diff changeset
119 end loop;
kono
parents:
diff changeset
120 M.Last := M.Last + Length;
kono
parents:
diff changeset
121 Last := First + Length - 1;
kono
parents:
diff changeset
122 end Fill_Buffer_Swap;
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124 ---------------
kono
parents:
diff changeset
125 -- To_String --
kono
parents:
diff changeset
126 ---------------
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 procedure To_String (SEA : Stream_Element_Array; S : out String) is
kono
parents:
diff changeset
129 pragma Assert (S'Length = 2 * SEA'Length);
kono
parents:
diff changeset
130 begin
kono
parents:
diff changeset
131 for J in SEA'Range loop
kono
parents:
diff changeset
132 declare
kono
parents:
diff changeset
133 S_J : constant Natural := 1 + Natural (J - SEA'First) * 2;
kono
parents:
diff changeset
134 begin
kono
parents:
diff changeset
135 S (S_J) := Hex_Digit (SEA (J) / 16);
kono
parents:
diff changeset
136 S (S_J + 1) := Hex_Digit (SEA (J) mod 16);
kono
parents:
diff changeset
137 end;
kono
parents:
diff changeset
138 end loop;
kono
parents:
diff changeset
139 end To_String;
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 -------
kono
parents:
diff changeset
142 -- H --
kono
parents:
diff changeset
143 -------
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 package body H is
kono
parents:
diff changeset
146
kono
parents:
diff changeset
147 procedure Update
kono
parents:
diff changeset
148 (C : in out Context;
kono
parents:
diff changeset
149 S : String;
kono
parents:
diff changeset
150 Fill_Buffer : Fill_Buffer_Access);
kono
parents:
diff changeset
151 -- Internal common routine for all Update procedures
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 procedure Final
kono
parents:
diff changeset
154 (C : Context;
kono
parents:
diff changeset
155 Hash_Bits : out Ada.Streams.Stream_Element_Array);
kono
parents:
diff changeset
156 -- Perform final hashing operations (data padding) and extract the
kono
parents:
diff changeset
157 -- (possibly truncated) state of C into Hash_Bits.
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 ------------
kono
parents:
diff changeset
160 -- Digest --
kono
parents:
diff changeset
161 ------------
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 function Digest (C : Context) return Message_Digest is
kono
parents:
diff changeset
164 Hash_Bits : Stream_Element_Array
kono
parents:
diff changeset
165 (1 .. Stream_Element_Offset (Hash_Length));
kono
parents:
diff changeset
166 begin
kono
parents:
diff changeset
167 Final (C, Hash_Bits);
kono
parents:
diff changeset
168 return MD : Message_Digest do
kono
parents:
diff changeset
169 To_String (Hash_Bits, MD);
kono
parents:
diff changeset
170 end return;
kono
parents:
diff changeset
171 end Digest;
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 function Digest (S : String) return Message_Digest is
kono
parents:
diff changeset
174 C : Context;
kono
parents:
diff changeset
175 begin
kono
parents:
diff changeset
176 Update (C, S);
kono
parents:
diff changeset
177 return Digest (C);
kono
parents:
diff changeset
178 end Digest;
kono
parents:
diff changeset
179
kono
parents:
diff changeset
180 function Digest (A : Stream_Element_Array) return Message_Digest is
kono
parents:
diff changeset
181 C : Context;
kono
parents:
diff changeset
182 begin
kono
parents:
diff changeset
183 Update (C, A);
kono
parents:
diff changeset
184 return Digest (C);
kono
parents:
diff changeset
185 end Digest;
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 function Digest (C : Context) return Binary_Message_Digest is
kono
parents:
diff changeset
188 Hash_Bits : Stream_Element_Array
kono
parents:
diff changeset
189 (1 .. Stream_Element_Offset (Hash_Length));
kono
parents:
diff changeset
190 begin
kono
parents:
diff changeset
191 Final (C, Hash_Bits);
kono
parents:
diff changeset
192 return Hash_Bits;
kono
parents:
diff changeset
193 end Digest;
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 function Digest (S : String) return Binary_Message_Digest is
kono
parents:
diff changeset
196 C : Context;
kono
parents:
diff changeset
197 begin
kono
parents:
diff changeset
198 Update (C, S);
kono
parents:
diff changeset
199 return Digest (C);
kono
parents:
diff changeset
200 end Digest;
kono
parents:
diff changeset
201
kono
parents:
diff changeset
202 function Digest
kono
parents:
diff changeset
203 (A : Stream_Element_Array) return Binary_Message_Digest
kono
parents:
diff changeset
204 is
kono
parents:
diff changeset
205 C : Context;
kono
parents:
diff changeset
206 begin
kono
parents:
diff changeset
207 Update (C, A);
kono
parents:
diff changeset
208 return Digest (C);
kono
parents:
diff changeset
209 end Digest;
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211 -----------
kono
parents:
diff changeset
212 -- Final --
kono
parents:
diff changeset
213 -----------
kono
parents:
diff changeset
214
kono
parents:
diff changeset
215 -- Once a complete message has been processed, it is padded with one 1
kono
parents:
diff changeset
216 -- bit followed by enough 0 bits so that the last block is 2 * Word'Size
kono
parents:
diff changeset
217 -- bits short of being completed. The last 2 * Word'Size bits are set to
kono
parents:
diff changeset
218 -- the message size in bits (excluding padding).
kono
parents:
diff changeset
219
kono
parents:
diff changeset
220 procedure Final
kono
parents:
diff changeset
221 (C : Context;
kono
parents:
diff changeset
222 Hash_Bits : out Stream_Element_Array)
kono
parents:
diff changeset
223 is
kono
parents:
diff changeset
224 FC : Context := C;
kono
parents:
diff changeset
225
kono
parents:
diff changeset
226 Zeroes : Natural;
kono
parents:
diff changeset
227 -- Number of 0 bytes in padding
kono
parents:
diff changeset
228
kono
parents:
diff changeset
229 Message_Length : Unsigned_64 := FC.M_State.Length;
kono
parents:
diff changeset
230 -- Message length in bytes
kono
parents:
diff changeset
231
kono
parents:
diff changeset
232 Size_Length : constant Natural :=
kono
parents:
diff changeset
233 2 * Hash_State.Word'Size / 8;
kono
parents:
diff changeset
234 -- Length in bytes of the size representation
kono
parents:
diff changeset
235
kono
parents:
diff changeset
236 begin
kono
parents:
diff changeset
237 Zeroes := (Block_Length - 1 - Size_Length - FC.M_State.Last)
kono
parents:
diff changeset
238 mod FC.M_State.Block_Length;
kono
parents:
diff changeset
239 declare
kono
parents:
diff changeset
240 Pad : String (1 .. 1 + Zeroes + Size_Length) :=
kono
parents:
diff changeset
241 (1 => Character'Val (128), others => ASCII.NUL);
kono
parents:
diff changeset
242
kono
parents:
diff changeset
243 Index : Natural;
kono
parents:
diff changeset
244 First_Index : Natural;
kono
parents:
diff changeset
245
kono
parents:
diff changeset
246 begin
kono
parents:
diff changeset
247 First_Index := (if Hash_Bit_Order = Low_Order_First
kono
parents:
diff changeset
248 then Pad'Last - Size_Length + 1
kono
parents:
diff changeset
249 else Pad'Last);
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 Index := First_Index;
kono
parents:
diff changeset
252 while Message_Length > 0 loop
kono
parents:
diff changeset
253 if Index = First_Index then
kono
parents:
diff changeset
254
kono
parents:
diff changeset
255 -- Message_Length is in bytes, but we need to store it as
kono
parents:
diff changeset
256 -- a bit count.
kono
parents:
diff changeset
257
kono
parents:
diff changeset
258 Pad (Index) := Character'Val
kono
parents:
diff changeset
259 (Shift_Left (Message_Length and 16#1f#, 3));
kono
parents:
diff changeset
260 Message_Length := Shift_Right (Message_Length, 5);
kono
parents:
diff changeset
261
kono
parents:
diff changeset
262 else
kono
parents:
diff changeset
263 Pad (Index) := Character'Val (Message_Length and 16#ff#);
kono
parents:
diff changeset
264 Message_Length := Shift_Right (Message_Length, 8);
kono
parents:
diff changeset
265 end if;
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267 Index := Index +
kono
parents:
diff changeset
268 (if Hash_Bit_Order = Low_Order_First then 1 else -1);
kono
parents:
diff changeset
269 end loop;
kono
parents:
diff changeset
270
kono
parents:
diff changeset
271 Update (FC, Pad);
kono
parents:
diff changeset
272 end;
kono
parents:
diff changeset
273
kono
parents:
diff changeset
274 pragma Assert (FC.M_State.Last = 0);
kono
parents:
diff changeset
275
kono
parents:
diff changeset
276 Hash_State.To_Hash (FC.H_State, Hash_Bits);
kono
parents:
diff changeset
277
kono
parents:
diff changeset
278 -- HMAC case: hash outer pad
kono
parents:
diff changeset
279
kono
parents:
diff changeset
280 if C.KL /= 0 then
kono
parents:
diff changeset
281 declare
kono
parents:
diff changeset
282 Outer_C : Context;
kono
parents:
diff changeset
283 Opad : Stream_Element_Array :=
kono
parents:
diff changeset
284 (1 .. Stream_Element_Offset (Block_Length) => 16#5c#);
kono
parents:
diff changeset
285
kono
parents:
diff changeset
286 begin
kono
parents:
diff changeset
287 for J in C.Key'Range loop
kono
parents:
diff changeset
288 Opad (J) := Opad (J) xor C.Key (J);
kono
parents:
diff changeset
289 end loop;
kono
parents:
diff changeset
290
kono
parents:
diff changeset
291 Update (Outer_C, Opad);
kono
parents:
diff changeset
292 Update (Outer_C, Hash_Bits);
kono
parents:
diff changeset
293
kono
parents:
diff changeset
294 Final (Outer_C, Hash_Bits);
kono
parents:
diff changeset
295 end;
kono
parents:
diff changeset
296 end if;
kono
parents:
diff changeset
297 end Final;
kono
parents:
diff changeset
298
kono
parents:
diff changeset
299 --------------------------
kono
parents:
diff changeset
300 -- HMAC_Initial_Context --
kono
parents:
diff changeset
301 --------------------------
kono
parents:
diff changeset
302
kono
parents:
diff changeset
303 function HMAC_Initial_Context (Key : String) return Context is
kono
parents:
diff changeset
304 begin
kono
parents:
diff changeset
305 if Key'Length = 0 then
kono
parents:
diff changeset
306 raise Constraint_Error with "null key";
kono
parents:
diff changeset
307 end if;
kono
parents:
diff changeset
308
kono
parents:
diff changeset
309 return C : Context (KL => (if Key'Length <= Key_Length'Last
kono
parents:
diff changeset
310 then Key'Length
kono
parents:
diff changeset
311 else Stream_Element_Offset (Hash_Length)))
kono
parents:
diff changeset
312 do
kono
parents:
diff changeset
313 -- Set Key (if longer than block length, first hash it)
kono
parents:
diff changeset
314
kono
parents:
diff changeset
315 if C.KL = Key'Length then
kono
parents:
diff changeset
316 declare
kono
parents:
diff changeset
317 SK : String (1 .. Key'Length);
kono
parents:
diff changeset
318 for SK'Address use C.Key'Address;
kono
parents:
diff changeset
319 pragma Import (Ada, SK);
kono
parents:
diff changeset
320 begin
kono
parents:
diff changeset
321 SK := Key;
kono
parents:
diff changeset
322 end;
kono
parents:
diff changeset
323
kono
parents:
diff changeset
324 else
kono
parents:
diff changeset
325 C.Key := Digest (Key);
kono
parents:
diff changeset
326 end if;
kono
parents:
diff changeset
327
kono
parents:
diff changeset
328 -- Hash inner pad
kono
parents:
diff changeset
329
kono
parents:
diff changeset
330 declare
kono
parents:
diff changeset
331 Ipad : Stream_Element_Array :=
kono
parents:
diff changeset
332 (1 .. Stream_Element_Offset (Block_Length) => 16#36#);
kono
parents:
diff changeset
333
kono
parents:
diff changeset
334 begin
kono
parents:
diff changeset
335 for J in C.Key'Range loop
kono
parents:
diff changeset
336 Ipad (J) := Ipad (J) xor C.Key (J);
kono
parents:
diff changeset
337 end loop;
kono
parents:
diff changeset
338
kono
parents:
diff changeset
339 Update (C, Ipad);
kono
parents:
diff changeset
340 end;
kono
parents:
diff changeset
341 end return;
kono
parents:
diff changeset
342 end HMAC_Initial_Context;
kono
parents:
diff changeset
343
kono
parents:
diff changeset
344 ----------
kono
parents:
diff changeset
345 -- Read --
kono
parents:
diff changeset
346 ----------
kono
parents:
diff changeset
347
kono
parents:
diff changeset
348 procedure Read
kono
parents:
diff changeset
349 (Stream : in out Hash_Stream;
kono
parents:
diff changeset
350 Item : out Stream_Element_Array;
kono
parents:
diff changeset
351 Last : out Stream_Element_Offset)
kono
parents:
diff changeset
352 is
kono
parents:
diff changeset
353 pragma Unreferenced (Stream, Item, Last);
kono
parents:
diff changeset
354 begin
kono
parents:
diff changeset
355 raise Program_Error with "Hash_Stream is write-only";
kono
parents:
diff changeset
356 end Read;
kono
parents:
diff changeset
357
kono
parents:
diff changeset
358 ------------
kono
parents:
diff changeset
359 -- Update --
kono
parents:
diff changeset
360 ------------
kono
parents:
diff changeset
361
kono
parents:
diff changeset
362 procedure Update
kono
parents:
diff changeset
363 (C : in out Context;
kono
parents:
diff changeset
364 S : String;
kono
parents:
diff changeset
365 Fill_Buffer : Fill_Buffer_Access)
kono
parents:
diff changeset
366 is
kono
parents:
diff changeset
367 Last : Natural;
kono
parents:
diff changeset
368
kono
parents:
diff changeset
369 begin
kono
parents:
diff changeset
370 C.M_State.Length := C.M_State.Length + S'Length;
kono
parents:
diff changeset
371
kono
parents:
diff changeset
372 Last := S'First - 1;
kono
parents:
diff changeset
373 while Last < S'Last loop
kono
parents:
diff changeset
374 Fill_Buffer (C.M_State, S, Last + 1, Last);
kono
parents:
diff changeset
375
kono
parents:
diff changeset
376 if C.M_State.Last = Block_Length then
kono
parents:
diff changeset
377 Transform (C.H_State, C.M_State);
kono
parents:
diff changeset
378 C.M_State.Last := 0;
kono
parents:
diff changeset
379 end if;
kono
parents:
diff changeset
380 end loop;
kono
parents:
diff changeset
381 end Update;
kono
parents:
diff changeset
382
kono
parents:
diff changeset
383 ------------
kono
parents:
diff changeset
384 -- Update --
kono
parents:
diff changeset
385 ------------
kono
parents:
diff changeset
386
kono
parents:
diff changeset
387 procedure Update (C : in out Context; Input : String) is
kono
parents:
diff changeset
388 begin
kono
parents:
diff changeset
389 Update (C, Input, Fill_Buffer_Copy'Access);
kono
parents:
diff changeset
390 end Update;
kono
parents:
diff changeset
391
kono
parents:
diff changeset
392 ------------
kono
parents:
diff changeset
393 -- Update --
kono
parents:
diff changeset
394 ------------
kono
parents:
diff changeset
395
kono
parents:
diff changeset
396 procedure Update (C : in out Context; Input : Stream_Element_Array) is
kono
parents:
diff changeset
397 S : String (1 .. Input'Length);
kono
parents:
diff changeset
398 for S'Address use Input'Address;
kono
parents:
diff changeset
399 pragma Import (Ada, S);
kono
parents:
diff changeset
400 begin
kono
parents:
diff changeset
401 Update (C, S, Fill_Buffer_Copy'Access);
kono
parents:
diff changeset
402 end Update;
kono
parents:
diff changeset
403
kono
parents:
diff changeset
404 -----------------
kono
parents:
diff changeset
405 -- Wide_Update --
kono
parents:
diff changeset
406 -----------------
kono
parents:
diff changeset
407
kono
parents:
diff changeset
408 procedure Wide_Update (C : in out Context; Input : Wide_String) is
kono
parents:
diff changeset
409 S : String (1 .. 2 * Input'Length);
kono
parents:
diff changeset
410 for S'Address use Input'Address;
kono
parents:
diff changeset
411 pragma Import (Ada, S);
kono
parents:
diff changeset
412 begin
kono
parents:
diff changeset
413 Update
kono
parents:
diff changeset
414 (C, S,
kono
parents:
diff changeset
415 (if System.Default_Bit_Order /= Low_Order_First
kono
parents:
diff changeset
416 then Fill_Buffer_Swap'Access
kono
parents:
diff changeset
417 else Fill_Buffer_Copy'Access));
kono
parents:
diff changeset
418 end Wide_Update;
kono
parents:
diff changeset
419
kono
parents:
diff changeset
420 -----------------
kono
parents:
diff changeset
421 -- Wide_Digest --
kono
parents:
diff changeset
422 -----------------
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 function Wide_Digest (W : Wide_String) return Message_Digest is
kono
parents:
diff changeset
425 C : Context;
kono
parents:
diff changeset
426 begin
kono
parents:
diff changeset
427 Wide_Update (C, W);
kono
parents:
diff changeset
428 return Digest (C);
kono
parents:
diff changeset
429 end Wide_Digest;
kono
parents:
diff changeset
430
kono
parents:
diff changeset
431 function Wide_Digest (W : Wide_String) return Binary_Message_Digest is
kono
parents:
diff changeset
432 C : Context;
kono
parents:
diff changeset
433 begin
kono
parents:
diff changeset
434 Wide_Update (C, W);
kono
parents:
diff changeset
435 return Digest (C);
kono
parents:
diff changeset
436 end Wide_Digest;
kono
parents:
diff changeset
437
kono
parents:
diff changeset
438 -----------
kono
parents:
diff changeset
439 -- Write --
kono
parents:
diff changeset
440 -----------
kono
parents:
diff changeset
441
kono
parents:
diff changeset
442 procedure Write
kono
parents:
diff changeset
443 (Stream : in out Hash_Stream;
kono
parents:
diff changeset
444 Item : Stream_Element_Array)
kono
parents:
diff changeset
445 is
kono
parents:
diff changeset
446 begin
kono
parents:
diff changeset
447 Update (Stream.C.all, Item);
kono
parents:
diff changeset
448 end Write;
kono
parents:
diff changeset
449
kono
parents:
diff changeset
450 end H;
kono
parents:
diff changeset
451
kono
parents:
diff changeset
452 -------------------------
kono
parents:
diff changeset
453 -- Hash_Function_State --
kono
parents:
diff changeset
454 -------------------------
kono
parents:
diff changeset
455
kono
parents:
diff changeset
456 package body Hash_Function_State is
kono
parents:
diff changeset
457
kono
parents:
diff changeset
458 -------------
kono
parents:
diff changeset
459 -- To_Hash --
kono
parents:
diff changeset
460 -------------
kono
parents:
diff changeset
461
kono
parents:
diff changeset
462 procedure To_Hash (H : State; H_Bits : out Stream_Element_Array) is
kono
parents:
diff changeset
463 Hash_Words : constant Natural := H'Size / Word'Size;
kono
parents:
diff changeset
464 Result : State (1 .. Hash_Words) :=
kono
parents:
diff changeset
465 H (H'Last - Hash_Words + 1 .. H'Last);
kono
parents:
diff changeset
466
kono
parents:
diff changeset
467 R_SEA : Stream_Element_Array (1 .. Result'Size / 8);
kono
parents:
diff changeset
468 for R_SEA'Address use Result'Address;
kono
parents:
diff changeset
469 pragma Import (Ada, R_SEA);
kono
parents:
diff changeset
470
kono
parents:
diff changeset
471 begin
kono
parents:
diff changeset
472 if System.Default_Bit_Order /= Hash_Bit_Order then
kono
parents:
diff changeset
473 for J in Result'Range loop
kono
parents:
diff changeset
474 Swap (Result (J)'Address);
kono
parents:
diff changeset
475 end loop;
kono
parents:
diff changeset
476 end if;
kono
parents:
diff changeset
477
kono
parents:
diff changeset
478 -- Return truncated hash
kono
parents:
diff changeset
479
kono
parents:
diff changeset
480 pragma Assert (H_Bits'Length <= R_SEA'Length);
kono
parents:
diff changeset
481 H_Bits := R_SEA (R_SEA'First .. R_SEA'First + H_Bits'Length - 1);
kono
parents:
diff changeset
482 end To_Hash;
kono
parents:
diff changeset
483
kono
parents:
diff changeset
484 end Hash_Function_State;
kono
parents:
diff changeset
485
kono
parents:
diff changeset
486 end GNAT.Secure_Hashes;