File : g-sechas.ads


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