-- (C) Copyright 2000 by John Halleck, All rights reserved. -- Basic support routines needed to allow SHA and DSA routines to run -- through the NIST tests. -- It is part of a project at http://www.cc.utah.edu/~nahaj/ with SHA.Process_Data; use SHA.Process_Data; with SHA.Strings; use SHA.Strings; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; with Ada.Characters.Handling; use Ada.Characters.Handling; package body NIST_Support is -- Copy a block of comments from one file to another. procedure Copy_Comments (Source, Destination : File_Type) is At_End : Boolean; Current : Character; Next : Character; begin while End_Of_Line (Source) and not End_Of_File (Source) loop Skip_Line (Source); end loop; if End_Of_File (Source) then return; end if; Look_Ahead (Source, Next, At_End); while not At_End and Next = '#' loop while not End_Of_Line (Source) loop Get (Source, Current); Put (Destination, Current); end loop; Skip_Line (Source); New_Line (Destination); Look_Ahead (Source, Next, At_End); end loop; end Copy_Comments; -- This searches for a specific string. It is *NOT* a general search, -- since it can't find strings where the initial part appears repeatedly -- in the file but at overlapping positions. This is just a quick hack. procedure Get_String (File : File_Type; Given : String; Reason : String) is Test : Character; Was_OK : Boolean; Line : Boolean; begin if Given'Length < 1 then raise Constraint_Error; end if; if End_Of_File (File) then Put (Standard_Error, "Looking for: """); Put (Standard_Error, Given); Put_Line (Standard_Error, """"); Put (Standard_Error, "Past end of file. ("); Put (Standard_Error, Reason); Put_Line (Standard_Error, ")"); raise NIST_File_Format_Error; end if; while not End_Of_File (File) loop if End_Of_Line (File) then Skip_Line (File); else Look_Ahead (File, Test, Line); if Test /= Given (Given'First) then Get (File, Test); else Was_OK := True; for I in Given'First .. Given'Last loop Get (File, Test); if Given (I) /= Test then Was_OK := False; exit; end if; end loop; if Was_OK then return; end if; end if; end if; end loop; Put (Standard_Error, "Unable to find string: """); Put (Standard_Error, Given); Put_Line (Standard_Error, """"); Put (Standard_Error, " ("); Put (Standard_Error, Reason); Put_Line (Standard_Error, ")"); raise NIST_File_Format_Error; end Get_String; procedure Add_Bit_String_To_Hash (File : File_Type) is Z, B : Integer; Input : Integer; begin Get (File, Z); Get (File, B); if B /= 0 and B /= 1 then Put_Line (Standard_Error, "Non-Binary initial binary value in bit string"); raise NIST_Number_Format_Error; end if; for J in 1 .. Z loop Get (File, Input); for I in 1 .. Input loop Add (Bit (B)); end loop; B := 1 - B; end loop; exception when Data_Error => Put_Line (Standard_Error, "Unable to read Integer while reading bit string"); raise; end Add_Bit_String_To_Hash; function Hash_Bit_String (File : File_Type) return Digest is Result : Digest; begin Initialize; Add_Bit_String_To_Hash (File); Finalize (Result); return Result; end Hash_Bit_String; function Find_Next_Bit_String (File : File_Type) return Boolean is Got : Character; Line_End : Boolean; begin while not End_Of_File (File) loop if End_Of_Line (File) then Skip_Line (File); else Look_Ahead (File, Got, Line_End); if Is_Digit (Got) then return True; end if; if Got = '<' then return False; end if; Get (File, Got); if Got /= ' ' and Got /= '^' and not Is_Control (Got) then return False; end if; end if; end loop; return False; end Find_Next_Bit_String; function Find_Hash (File : File_Type) return Boolean is Got : Character; Line_End : Boolean; begin while not End_Of_File (File) loop if End_Of_Line (File) then Skip_Line (File); else Look_Ahead (File, Got, Line_End); if Is_Hexadecimal_Digit (Got) then return True; end if; if Got = '<' then return False; end if; Get (File, Got); if Got /= ' ' and Got /= '^' and not Is_Control (Got) then return False; end if; end if; end loop; return False; end Find_Hash; procedure Compare_Hash (File : File_Type; Hash : Hex_SHA_String) is Got : Character; begin for I in Hash'First .. Hash'Last loop if End_Of_File (File) then raise NIST_File_Format_Error; elsif End_Of_Line (File) then raise NIST_File_Format_Error; end if; Get (File, Got); if not Is_Hexadecimal_Digit (Got) then raise NIST_File_Format_Error; elsif Got /= Hash (I) then raise NIST_Test_Failed_Error; end if; end loop; end Compare_Hash; end NIST_Support;