1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
|
------------------------------------------------------------------------------
-- --
-- GNAT LIBRARY COMPONENTS --
-- --
-- G N A T . S E C U R E _ H A S H E S --
-- --
-- S p e c --
-- --
-- Copyright (C) 2009-2018, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- ware Foundation; either version 3, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. --
-- --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception, --
-- version 3.1, as published by the Free Software Foundation. --
-- --
-- You should have received a copy of the GNU General Public License and --
-- a copy of the GCC Runtime Library Exception along with this program; --
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
-- <http://www.gnu.org/licenses/>. --
-- --
-- GNAT was originally developed by the GNAT team at New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc. --
-- --
------------------------------------------------------------------------------
-- This package provides common supporting code for a family of secure
-- hash functions (including MD5 and the FIPS PUB 180-3 functions SHA-1,
-- SHA-224, SHA-256, SHA-384 and SHA-512).
-- This is an internal unit and should be not used directly in applications.
-- Use GNAT.MD5 and GNAT.SHA* instead.
with Ada.Streams; use Ada.Streams;
with Interfaces;
with System;
package GNAT.Secure_Hashes is
type Buffer_Type is new String;
for Buffer_Type'Alignment use 8;
-- Secure hash functions use a string buffer that is also accessed as an
-- array of words, which may require up to 64 bit alignment.
-- The function-independent part of processing state: A buffer of data
-- being accumulated until a complete block is ready for hashing.
type Message_State (Block_Length : Natural) is record
Last : Natural := 0;
-- Index of last used element in Buffer
Length : Interfaces.Unsigned_64 := 0;
-- Total length of processed data
Buffer : Buffer_Type (1 .. Block_Length);
-- Data buffer
end record;
-- The function-specific part of processing state:
-- Each hash function maintains an internal state as an array of words,
-- which is ultimately converted to a stream representation with the
-- appropriate bit order.
generic
type Word is mod <>;
-- Either 32 or 64 bits
with procedure Swap (X : System.Address);
-- Byte swapping function for a Word at X
Hash_Bit_Order : System.Bit_Order;
-- Bit order of the produced hash
package Hash_Function_State is
type State is array (Natural range <>) of Word;
-- Used to store a hash function's internal state
procedure To_Hash
(H : State;
H_Bits : out Stream_Element_Array);
-- Convert H to stream representation with the given bit order. If
-- H_Bits is smaller than the internal hash state, then the state
-- is truncated.
end Hash_Function_State;
-- Generic hashing framework: The user interface for each implemented
-- secure hash function is an instance of this generic package.
generic
Block_Words : Natural;
-- Number of words in each block
State_Words : Natural;
-- Number of words in internal state
Hash_Words : Natural;
-- Number of words in the final hash (must be no greater than
-- State_Words).
Hash_Bit_Order : System.Bit_Order;
-- Bit order used for conversion between bit representation and word
-- representation.
with package Hash_State is new Hash_Function_State (<>);
-- Hash function state package
Initial_State : Hash_State.State;
-- Initial value of the hash function state
with procedure Transform
(H : in out Hash_State.State;
M : in out Message_State);
-- Transformation function updating H by processing a complete data
-- block from M.
package H is
-- The visible part of H is the interface to secure hashing functions
-- that is exposed to user applications, and is intended to remain
-- a stable interface.
pragma Assert (Hash_Words <= State_Words);
type Context is private;
-- The internal processing state of the hashing function
function "=" (L, R : Context) return Boolean is abstract;
-- Context is the internal, implementation defined intermediate state
-- in a hash computation, and no specific semantics can be expected on
-- equality of context values. Only equality of final hash values (as
-- returned by the [Wide_]Digest functions below) is meaningful.
Initial_Context : constant Context;
-- Initial value of a Context object. May be used to reinitialize
-- a Context value by simple assignment of this value to the object.
function HMAC_Initial_Context (Key : String) return Context;
-- Initial Context for HMAC computation with the given Key
procedure Update (C : in out Context; Input : String);
procedure Wide_Update (C : in out Context; Input : Wide_String);
procedure Update
(C : in out Context;
Input : Stream_Element_Array);
-- Update C to process the given input. Successive calls to Update are
-- equivalent to a single call with the concatenation of the inputs. For
-- the Wide_String version, each Wide_Character is processed low order
-- byte first.
Word_Length : constant Natural := Hash_State.Word'Size / 8;
Hash_Length : constant Natural := Hash_Words * Word_Length;
subtype Binary_Message_Digest is
Stream_Element_Array (1 .. Stream_Element_Offset (Hash_Length));
-- The fixed-length byte array returned by Digest, providing
-- the hash in binary representation.
function Digest (C : Context) return Binary_Message_Digest;
-- Return hash or HMAC for the data accumulated with C
function Digest (S : String) return Binary_Message_Digest;
function Wide_Digest (W : Wide_String) return Binary_Message_Digest;
function Digest
(A : Stream_Element_Array) return Binary_Message_Digest;
-- These functions are equivalent to the corresponding Update (or
-- Wide_Update) on a default initialized Context, followed by Digest
-- on the resulting Context.
subtype Message_Digest is String (1 .. 2 * Hash_Length);
-- The fixed-length string returned by Digest, providing the hash in
-- hexadecimal representation.
function Digest (C : Context) return Message_Digest;
-- Return hash or HMAC for the data accumulated with C in hexadecimal
-- representation.
function Digest (S : String) return Message_Digest;
function Wide_Digest (W : Wide_String) return Message_Digest;
function Digest (A : Stream_Element_Array) return Message_Digest;
-- These functions are equivalent to the corresponding Update (or
-- Wide_Update) on a default initialized Context, followed by Digest
-- on the resulting Context.
type Hash_Stream (C : access Context) is
new Root_Stream_Type with private;
-- Stream wrapper converting Write calls to Update calls on C.
-- Arbitrary data structures can thus be conveniently hashed using
-- their stream attributes.
private
Block_Length : constant Natural := Block_Words * Word_Length;
-- Length in bytes of a data block
subtype Key_Length is
Stream_Element_Offset range 0 .. Stream_Element_Offset (Block_Length);
-- KL is 0 for a normal hash context, > 0 for HMAC
type Context (KL : Key_Length := 0) is record
H_State : Hash_State.State (0 .. State_Words - 1) := Initial_State;
-- Function-specific state
M_State : Message_State (Block_Length);
-- Function-independent state (block buffer)
Key : Stream_Element_Array (1 .. KL);
-- HMAC key
end record;
Initial_Context : constant Context (KL => 0) := (others => <>);
-- Initial values are provided by default initialization of Context
type Hash_Stream (C : access Context) is
new Root_Stream_Type with null record;
procedure Read
(Stream : in out Hash_Stream;
Item : out Stream_Element_Array;
Last : out Stream_Element_Offset);
-- Raise Program_Error: hash streams are write-only
procedure Write
(Stream : in out Hash_Stream;
Item : Stream_Element_Array);
-- Call Update
end H;
end GNAT.Secure_Hashes;
|