------------------------------------------------------------------------------
--                                                                          --
--                         GNAT LIBRARY COMPONENTS                          --
--                                                                          --
--                   G N A T . S E C U R E _ H A S H E S                    --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 2009-2021, 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.      --
--                                                                          --
------------------------------------------------------------------------------

with System;     use System;
with Interfaces; use Interfaces;

package body GNAT.Secure_Hashes is

   Hex_Digit : constant array (Stream_Element range 0 .. 15) of Character :=
                 "0123456789abcdef";

   type Fill_Buffer_Access is
     not null access procedure
       (M     : in out Message_State;
        SEA   : Stream_Element_Array;
        First : Stream_Element_Offset;
        Last  : out Stream_Element_Offset);
   --  A procedure to transfer data from SEA, starting at First, into M's block
   --  buffer until either the block buffer is full or all data from S has been
   --  consumed.

   procedure Fill_Buffer_Copy
     (M     : in out Message_State;
      SEA   : Stream_Element_Array;
      First : Stream_Element_Offset;
      Last  : out Stream_Element_Offset);
   --  Transfer procedure which just copies data from S to M

   procedure Fill_Buffer_Swap
     (M     : in out Message_State;
      SEA   : Stream_Element_Array;
      First : Stream_Element_Offset;
      Last  : out Stream_Element_Offset);
   --  Transfer procedure which swaps bytes from S when copying into M. S must
   --  have even length. Note that the swapping is performed considering pairs
   --  starting at S'First, even if S'First /= First (that is, if
   --  First = S'First then the first copied byte is always S (S'First + 1),
   --  and if First = S'First + 1 then the first copied byte is always
   --  S (S'First).

   procedure To_String (SEA : Stream_Element_Array; S : out String);
   --  Return the hexadecimal representation of SEA

   ----------------------
   -- Fill_Buffer_Copy --
   ----------------------

   procedure Fill_Buffer_Copy
     (M     : in out Message_State;
      SEA   : Stream_Element_Array;
      First : Stream_Element_Offset;
      Last  : out Stream_Element_Offset)
   is
      Buf_SEA : Stream_Element_Array (M.Buffer'Range);
      for Buf_SEA'Address use M.Buffer'Address;
      pragma Import (Ada, Buf_SEA);

      Length : constant Stream_Element_Offset :=
                 Stream_Element_Offset'Min
                    (M.Block_Length - M.Last, SEA'Last - First + 1);

   begin
      pragma Assert (Length > 0);

      Buf_SEA (M.Last + 1 .. M.Last + Length) :=
        SEA (First .. First + Length - 1);
      M.Last := M.Last + Length;
      Last := First + Length - 1;
   end Fill_Buffer_Copy;

   ----------------------
   -- Fill_Buffer_Swap --
   ----------------------

   procedure Fill_Buffer_Swap
     (M     : in out Message_State;
      SEA   : Stream_Element_Array;
      First : Stream_Element_Offset;
      Last  : out Stream_Element_Offset)
   is
      pragma Assert (SEA'Length mod 2 = 0);
      Length : constant Stream_Element_Offset :=
                  Stream_Element_Offset'Min
                     (M.Block_Length - M.Last, SEA'Last - First + 1);
   begin
      Last := First;
      while Last - First < Length loop
         M.Buffer (M.Last + 1 + Last - First) :=
           (if (Last - SEA'First) mod 2 = 0
            then SEA (Last + 1)
            else SEA (Last - 1));
         Last := Last + 1;
      end loop;
      M.Last := M.Last + Length;
      Last := First + Length - 1;
   end Fill_Buffer_Swap;

   ---------------
   -- To_String --
   ---------------

   procedure To_String (SEA : Stream_Element_Array; S : out String) is
      pragma Assert (S'Length = 2 * SEA'Length);
   begin
      for J in SEA'Range loop
         declare
            S_J : constant Natural := 1 + Natural (J - SEA'First) * 2;
         begin
            S (S_J)     := Hex_Digit (SEA (J) / 16);
            S (S_J + 1) := Hex_Digit (SEA (J) mod 16);
         end;
      end loop;
   end To_String;

   -------
   -- H --
   -------

   package body H is

      procedure Update
        (C           : in out Context;
         SEA         : Stream_Element_Array;
         Fill_Buffer : Fill_Buffer_Access);
      --  Internal common routine for all Update procedures

      procedure Final
        (C         : Context;
         Hash_Bits : out Ada.Streams.Stream_Element_Array);
      --  Perform final hashing operations (data padding) and extract the
      --  (possibly truncated) state of C into Hash_Bits.

      ------------
      -- Digest --
      ------------

      function Digest (C : Context) return Message_Digest is
         Hash_Bits : Stream_Element_Array (1 .. Hash_Length);
      begin
         Final (C, Hash_Bits);
         return MD : Message_Digest do
            To_String (Hash_Bits, MD);
         end return;
      end Digest;

      function Digest (S : String) return Message_Digest is
         C : Context;
      begin
         Update (C, S);
         return Digest (C);
      end Digest;

      function Digest (A : Stream_Element_Array) return Message_Digest is
         C : Context;
      begin
         Update (C, A);
         return Digest (C);
      end Digest;

      function Digest (C : Context) return Binary_Message_Digest is
         Hash_Bits : Stream_Element_Array (1 .. Hash_Length);
      begin
         Final (C, Hash_Bits);
         return Hash_Bits;
      end Digest;

      function Digest (S : String) return Binary_Message_Digest is
         C : Context;
      begin
         Update (C, S);
         return Digest (C);
      end Digest;

      function Digest
        (A : Stream_Element_Array) return Binary_Message_Digest
      is
         C : Context;
      begin
         Update (C, A);
         return Digest (C);
      end Digest;

      -----------
      -- Final --
      -----------

      --  Once a complete message has been processed, it is padded with one 1
      --  bit followed by enough 0 bits so that the last block is 2 * Word'Size
      --  bits short of being completed. The last 2 * Word'Size bits are set to
      --  the message size in bits (excluding padding).

      procedure Final
        (C         : Context;
         Hash_Bits : out Stream_Element_Array)
      is
         FC : Context := C;

         Zeroes : Stream_Element_Count;
         --  Number of 0 bytes in padding

         Message_Length : Unsigned_64 := FC.M_State.Length;
         --  Message length in bytes

         Size_Length : constant Stream_Element_Count :=
                         2 * Hash_State.Word'Size / 8;
         --  Length in bytes of the size representation

      begin
         Zeroes := (Block_Length - 1 - Size_Length - FC.M_State.Last)
                     mod FC.M_State.Block_Length;
         declare
            Pad : Stream_Element_Array (1 .. 1 + Zeroes + Size_Length) :=
                    (1 => 128, others => 0);

            Index       : Stream_Element_Offset;
            First_Index : Stream_Element_Offset;

         begin
            First_Index := (if Hash_Bit_Order = Low_Order_First
                            then Pad'Last - Size_Length + 1
                            else Pad'Last);

            Index := First_Index;
            while Message_Length > 0 loop
               if Index = First_Index then

                  --  Message_Length is in bytes, but we need to store it as
                  --  a bit count.

                  Pad (Index) := Stream_Element
                                   (Shift_Left (Message_Length and 16#1f#, 3));
                  Message_Length := Shift_Right (Message_Length, 5);

               else
                  Pad (Index) := Stream_Element (Message_Length and 16#ff#);
                  Message_Length := Shift_Right (Message_Length, 8);
               end if;

               Index := Index +
                          (if Hash_Bit_Order = Low_Order_First then 1 else -1);
            end loop;

            Update (FC, Pad);
         end;

         pragma Assert (FC.M_State.Last = 0);

         Hash_State.To_Hash (FC.H_State, Hash_Bits);

         --  HMAC case: hash outer pad

         if C.KL /= 0 then
            declare
               Outer_C : Context;
               Opad    : Stream_Element_Array :=
                 (1 .. Stream_Element_Offset (Block_Length) => 16#5c#);

            begin
               for J in C.Key'Range loop
                  Opad (J) := Opad (J) xor C.Key (J);
               end loop;

               Update (Outer_C, Opad);
               Update (Outer_C, Hash_Bits);

               Final (Outer_C, Hash_Bits);
            end;
         end if;
      end Final;

      --------------------------
      -- HMAC_Initial_Context --
      --------------------------

      function HMAC_Initial_Context (Key : String) return Context is
      begin
         if Key'Length = 0 then
            raise Constraint_Error with "null key";
         end if;

         return C : Context (KL => (if Key'Length <= Key_Length'Last
                                    then Key'Length
                                    else Hash_Length))
         do
            --  Set Key (if longer than block length, first hash it)

            if C.KL = Key'Length then
               declare
                  SK : String (1 .. Key'Length);
                  for SK'Address use C.Key'Address;
                  pragma Import (Ada, SK);
               begin
                  SK := Key;
               end;

            else
               C.Key := Digest (Key);
            end if;

            --  Hash inner pad

            declare
               Ipad : Stream_Element_Array :=
                 (1 .. Stream_Element_Offset (Block_Length) => 16#36#);

            begin
               for J in C.Key'Range loop
                  Ipad (J) := Ipad (J) xor C.Key (J);
               end loop;

               Update (C, Ipad);
            end;
         end return;
      end HMAC_Initial_Context;

      ----------
      -- Read --
      ----------

      procedure Read
        (Stream : in out Hash_Stream;
         Item   : out Stream_Element_Array;
         Last   : out Stream_Element_Offset)
      is
         pragma Unreferenced (Stream, Item, Last);
      begin
         raise Program_Error with "Hash_Stream is write-only";
      end Read;

      ------------
      -- Update --
      ------------

      procedure Update
        (C           : in out Context;
         SEA         : Stream_Element_Array;
         Fill_Buffer : Fill_Buffer_Access)
      is
         First, Last : Stream_Element_Offset;

      begin
         if SEA'Length = 0 then
            return;
         end if;

         C.M_State.Length := C.M_State.Length + SEA'Length;

         First := SEA'First;
         loop
            Fill_Buffer (C.M_State, SEA, First, Last);

            if C.M_State.Last = Block_Length then
               Transform (C.H_State, C.M_State);
               C.M_State.Last := 0;
            end if;

            exit when Last = SEA'Last;
            First := Last + 1;
         end loop;
      end Update;

      ------------
      -- Update --
      ------------

      procedure Update (C : in out Context; Input : Stream_Element_Array) is
      begin
         Update (C, Input, Fill_Buffer_Copy'Access);
      end Update;

      ------------
      -- Update --
      ------------

      procedure Update (C : in out Context; Input : String) is
         pragma Assert (Input'Length <= Stream_Element_Offset'Last);
         SEA : Stream_Element_Array (1 .. Input'Length);
         for SEA'Address use Input'Address;
         pragma Import (Ada, SEA);
      begin
         Update (C, SEA, Fill_Buffer_Copy'Access);
      end Update;

      -----------------
      -- Wide_Update --
      -----------------

      procedure Wide_Update (C : in out Context; Input : Wide_String) is
         SEA : Stream_Element_Array (1 .. 2 * Input'Length);
         for SEA'Address use Input'Address;
         pragma Import (Ada, SEA);
      begin
         Update
           (C, SEA,
            (if System.Default_Bit_Order /= Low_Order_First
             then Fill_Buffer_Swap'Access
             else Fill_Buffer_Copy'Access));
      end Wide_Update;

      -----------------
      -- Wide_Digest --
      -----------------

      function Wide_Digest (W : Wide_String) return Message_Digest is
         C : Context;
      begin
         Wide_Update (C, W);
         return Digest (C);
      end Wide_Digest;

      function Wide_Digest (W : Wide_String) return Binary_Message_Digest is
         C : Context;
      begin
         Wide_Update (C, W);
         return Digest (C);
      end Wide_Digest;

      -----------
      -- Write --
      -----------

      procedure Write
         (Stream : in out Hash_Stream;
          Item   : Stream_Element_Array)
      is
      begin
         Update (Stream.C.all, Item);
      end Write;

   end H;

   -------------------------
   -- Hash_Function_State --
   -------------------------

   package body Hash_Function_State is

      -------------
      -- To_Hash --
      -------------

      procedure To_Hash (H : State; H_Bits : out Stream_Element_Array) is
         Hash_Words : constant Stream_Element_Offset := H'Size / Word'Size;
         Result     : State (1 .. Hash_Words) :=
                        H (H'Last - Hash_Words + 1 .. H'Last);

         R_SEA : Stream_Element_Array (1 .. Result'Size / 8);
         for R_SEA'Address use Result'Address;
         pragma Import (Ada, R_SEA);

      begin
         if System.Default_Bit_Order /= Hash_Bit_Order then
            for J in Result'Range loop
               Swap (Result (J)'Address);
            end loop;
         end if;

         --  Return truncated hash

         pragma Assert (H_Bits'Length <= R_SEA'Length);
         H_Bits := R_SEA (R_SEA'First .. R_SEA'First + H_Bits'Length - 1);
      end To_Hash;

   end Hash_Function_State;

end GNAT.Secure_Hashes;
