raw
smg_comms_skeys_s...    1  -- Message reader & writers for SMG Communication Protocol
smg_comms_skeys_s... 2 -- S.MG, 2018
smg_comms_skeys_s... 3
smg_comms_skeys_s... 4 with Interfaces; use Interfaces;
smg_comms_skeys_s... 5 with Serpent;
smg_comms_skeys_s... 6 with System; use System;
smg_comms_skeys_s... 7
smg_comms_skeys_s... 8 package body Messages is
smg_comms_skeys_s... 9
smg_comms_skeys_s... 10 procedure Write_SKeys_SMsg( Keyset : in Serpent_Keyset;
smg_comms_skeys_s... 11 Counter : in Interfaces.Unsigned_16;
smg_comms_skeys_s... 12 Msg : out Raw_Types.Serpent_Msg) is
smg_comms_skeys_s... 13 Pos : Integer := Msg'First;
smg_comms_skeys_s... 14 Check : CRC32.CRC32;
smg_comms_skeys_s... 15 PadLen: Integer;
smg_comms_skeys_s... 16 K : Serpent.Key;
smg_comms_skeys_s... 17 begin
smg_comms_skeys_s... 18 -- write Type ID
smg_comms_skeys_s... 19 Msg(Pos) := SKeys_S_Type;
smg_comms_skeys_s... 20 Pos := Pos + 1;
smg_comms_skeys_s... 21
smg_comms_skeys_s... 22 -- write count of keys (NB: this IS 8 bits by definition)
smg_comms_skeys_s... 23 Msg(Pos) := Keyset.Keys'Length;
smg_comms_skeys_s... 24 Pos := Pos + 1;
smg_comms_skeys_s... 25
smg_comms_skeys_s... 26 -- write keys
smg_comms_skeys_s... 27 for I in Keyset.Keys'Range loop
smg_comms_skeys_s... 28 -- retrieve Key to write
smg_comms_skeys_s... 29 K := Keyset.Keys( I );
smg_comms_skeys_s... 30
smg_comms_skeys_s... 31 -- write key itself
smg_comms_skeys_s... 32 Msg(Pos..Pos+K'Length-1) := K;
smg_comms_skeys_s... 33 -- ensure little endian order in message
smg_comms_skeys_s... 34 Cast_LE(Msg(Pos..Pos+K'Length-1));
smg_comms_skeys_s... 35 Pos := Pos + K'Length;
smg_comms_skeys_s... 36
smg_comms_skeys_s... 37 -- write CRC of key
smg_comms_skeys_s... 38 Check := CRC32.CRC( K );
smg_comms_skeys_s... 39 Msg(Pos..Pos+3) := Raw_Types.Cast(Check);
smg_comms_skeys_s... 40 Cast_LE(Msg(Pos..Pos+3));
smg_comms_skeys_s... 41 Pos := Pos + 4;
smg_comms_skeys_s... 42 end loop;
smg_comms_skeys_s... 43
smg_comms_skeys_s... 44 -- write flag
smg_comms_skeys_s... 45 Msg(Pos) := Keyset.Flag;
smg_comms_skeys_s... 46 Pos := Pos + 1;
smg_comms_skeys_s... 47
smg_comms_skeys_s... 48 -- write message counter
smg_comms_skeys_s... 49 Msg(Pos..Pos+1) := Raw_Types.Cast(Counter);
smg_comms_skeys_s... 50 Cast_LE(Msg(Pos..Pos+1));
smg_comms_skeys_s... 51 Pos := Pos + 2;
smg_comms_skeys_s... 52
smg_comms_skeys_s... 53 -- write padding as needed; endianness is irrelevant here
smg_comms_skeys_s... 54 PadLen := Msg'Last - Pos + 1;
smg_comms_skeys_s... 55 if PadLen > 0 then
smg_comms_skeys_s... 56 declare
smg_comms_skeys_s... 57 Pad : Raw_Types.Octets(1..PadLen);
smg_comms_skeys_s... 58 begin
smg_comms_skeys_s... 59 RNG.Get_Octets( Pad );
smg_comms_skeys_s... 60 Msg(Pos..Pos+PadLen-1) := Pad;
smg_comms_skeys_s... 61 end;
smg_comms_skeys_s... 62 end if;
smg_comms_skeys_s... 63 end Write_SKeys_SMsg;
smg_comms_skeys_s... 64
smg_comms_skeys_s... 65
smg_comms_skeys_s... 66 -- Reads a Serpent keyset from given Serpent Message
smg_comms_skeys_s... 67 procedure Read_SKeys_SMsg( Msg : in Raw_Types.Serpent_Msg;
smg_comms_skeys_s... 68 Counter : out Interfaces.Unsigned_16;
smg_comms_skeys_s... 69 Keyset : out Serpent_Keyset) is
smg_comms_skeys_s... 70 Pos: Integer := Msg'First;
smg_comms_skeys_s... 71 begin
smg_comms_skeys_s... 72 -- read type and check
smg_comms_skeys_s... 73 if Msg(Pos) = SKeys_S_Type then
smg_comms_skeys_s... 74 Pos := Pos + 1;
smg_comms_skeys_s... 75 else
smg_comms_skeys_s... 76 raise Invalid_Msg;
smg_comms_skeys_s... 77 end if;
smg_comms_skeys_s... 78
smg_comms_skeys_s... 79 -- read count of keys and check
smg_comms_skeys_s... 80 if Msg(Pos) in Keys_Count'Range then
smg_comms_skeys_s... 81 declare
smg_comms_skeys_s... 82 N : Keys_Count := Keys_Count(Msg(Pos));
smg_comms_skeys_s... 83 KS : Serpent_Keyset(N);
smg_comms_skeys_s... 84 K : Serpent.Key;
smg_comms_skeys_s... 85 Check : CRC32.CRC32;
smg_comms_skeys_s... 86 O4 : Raw_Types.Octets_4;
smg_comms_skeys_s... 87 O2 : Raw_Types.Octets_2;
smg_comms_skeys_s... 88 begin
smg_comms_skeys_s... 89 Pos := Pos + 1;
smg_comms_skeys_s... 90 --read keys and check crc for each
smg_comms_skeys_s... 91 for I in 1 .. N loop
smg_comms_skeys_s... 92 -- read key and advance pos
smg_comms_skeys_s... 93 K := Msg(Pos..Pos+K'Length-1);
smg_comms_skeys_s... 94 Cast_LE(K);
smg_comms_skeys_s... 95 Pos := Pos + K'Length;
smg_comms_skeys_s... 96 -- read crc and compare to crc32(key)
smg_comms_skeys_s... 97 O4 := Msg(Pos..Pos+3);
smg_comms_skeys_s... 98 Cast_LE(O4);
smg_comms_skeys_s... 99 Check := Raw_Types.Cast(O4);
smg_comms_skeys_s... 100 Pos := Pos + 4;
smg_comms_skeys_s... 101 if Check /= CRC32.CRC(K) then
smg_comms_skeys_s... 102 raise Invalid_Msg;
smg_comms_skeys_s... 103 end if;
smg_comms_skeys_s... 104 -- if it got here, key is fine so add to set
smg_comms_skeys_s... 105 KS.Keys(KS.Keys'First + I -1) := K;
smg_comms_skeys_s... 106 end loop;
smg_comms_skeys_s... 107 -- read and set flag
smg_comms_skeys_s... 108 KS.Flag := Msg(Pos);
smg_comms_skeys_s... 109 Pos := Pos + 1;
smg_comms_skeys_s... 110 -- read and set message counter
smg_comms_skeys_s... 111 O2 := Msg(Pos..Pos+1);
smg_comms_skeys_s... 112 Cast_LE(O2);
smg_comms_skeys_s... 113 Counter := Raw_Types.Cast(O2);
smg_comms_skeys_s... 114 -- rest of message is padding so it's ignored
smg_comms_skeys_s... 115 -- copy keyset to output variable
smg_comms_skeys_s... 116 Keyset := KS;
smg_comms_skeys_s... 117 end;
smg_comms_skeys_s... 118 else
smg_comms_skeys_s... 119 raise Invalid_Msg;
smg_comms_skeys_s... 120 end if;
smg_comms_skeys_s... 121 end Read_SKeys_SMsg;
smg_comms_skeys_s... 122
smg_comms_skeys_s... 123 -- private part
smg_comms_skeys_s... 124 procedure Cast_LE( LE: in out Raw_Types.Octets ) is
smg_comms_skeys_s... 125 begin
smg_comms_skeys_s... 126 -- flip octets ONLY if native is big endian.
smg_comms_skeys_s... 127 if System.Default_Bit_Order = System.High_Order_First then
smg_comms_skeys_s... 128 declare
smg_comms_skeys_s... 129 BE: constant Raw_Types.Octets := LE;
smg_comms_skeys_s... 130 begin
smg_comms_skeys_s... 131 for I in 1..LE'Length loop
smg_comms_skeys_s... 132 LE(LE'First+I-1) := BE(BE'Last-I+1);
smg_comms_skeys_s... 133 end loop;
smg_comms_skeys_s... 134 end;
smg_comms_skeys_s... 135 end if;
smg_comms_skeys_s... 136 -- NOTHING to do for native little endian
smg_comms_skeys_s... 137 end Cast_LE;
smg_comms_skeys_s... 138
smg_comms_skeys_s... 139 end Messages;