diff options
author | Arnaud Charlet <charlet@gcc.gnu.org> | 2014-08-04 14:47:56 +0200 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2014-08-04 14:47:56 +0200 |
commit | 4ff2b6dcc98d42fb75c4491ab3871cef10857ebf (patch) | |
tree | f3848bfb928022bf983a63f33a0f1da48ac0aa85 /gcc/ada/g-sechas.adb | |
parent | e72a92e447fc0d13a6744e4d4a5e2c50c8515f79 (diff) | |
download | gcc-4ff2b6dcc98d42fb75c4491ab3871cef10857ebf.zip gcc-4ff2b6dcc98d42fb75c4491ab3871cef10857ebf.tar.gz gcc-4ff2b6dcc98d42fb75c4491ab3871cef10857ebf.tar.bz2 |
[multiple changes]
2014-08-04 Robert Dewar <dewar@adacore.com>
* sem_prag.adb, osint.adb, osint.ads: Minor reformatting.
2014-08-04 Yannick Moy <moy@adacore.com>
* sem_ch3.adb (Derive_Type_Declaration,
Process_Discriminants): Remove SPARK-specific legality checks.
2014-08-04 Thomas Quinot <quinot@adacore.com>
* g-sechas.ads, g-sechas.adb (HMAC_Initial_Context): New subprogram.
* gnat_rm.texi (GNAT.MD5/SHA1/SHA224/SHA256/SHA512): Document support
for HMAC.
From-SVN: r213577
Diffstat (limited to 'gcc/ada/g-sechas.adb')
-rw-r--r-- | gcc/ada/g-sechas.adb | 74 |
1 files changed, 70 insertions, 4 deletions
diff --git a/gcc/ada/g-sechas.adb b/gcc/ada/g-sechas.adb index 4b396f1..0e70b5d 100644 --- a/gcc/ada/g-sechas.adb +++ b/gcc/ada/g-sechas.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2009-2012, Free Software Foundation, Inc. -- +-- Copyright (C) 2009-2014, 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- -- @@ -218,8 +218,8 @@ package body GNAT.Secure_Hashes is -- the message size in bits (excluding padding). procedure Final - (C : Context; - Hash_Bits : out Stream_Element_Array) + (C : Context; + Hash_Bits : out Stream_Element_Array) is FC : Context := C; @@ -274,8 +274,73 @@ package body GNAT.Secure_Hashes is 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 Stream_Element_Offset (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; + ------------ -- Update -- ------------ @@ -285,11 +350,12 @@ package body GNAT.Secure_Hashes is S : String; Fill_Buffer : Fill_Buffer_Access) is - Last : Natural := S'First - 1; + Last : Natural; begin C.M_State.Length := C.M_State.Length + S'Length; + Last := S'First - 1; while Last < S'Last loop Fill_Buffer (C.M_State, S, Last + 1, Last); |