- 899126526FA67B199AE8B8C17F0DCBBB68F59E0C6E88BFB21DACAC13D02FC11F3C6A2AF97920AFD44660C7AC689B51D474E3671CDDEE4443EEEAA5891CA374E6+ 796122DCF307899111D2909509460B1DE5215EF1DFADB88AF3F3B2654754AA225ACF79FF0B50BE884F184966920BCD30E236585FA46846DC36B8F58F67C726D1smg_comms/src/messages.adb(7 . 16)(7 . 128)
52
53 package body Messages is
54
55 ----------------------
56 -- Serpent Messages --
57 ----------------------
58
59 procedure Write_SKeys_SMsg( Keyset : in Serpent_Keyset;
60 Counter : in Interfaces.Unsigned_16;
61 Msg : out Raw_Types.Serpent_Msg) is
62 begin
63 -- call internal write on Octets with correct type id
64 Write_SKeys( Keyset, Counter, SKeys_S_Type, Msg );
65 end Write_SKeys_SMsg;
66
67
68 -- Reads a Serpent keyset from given Serpent Message
69 procedure Read_SKeys_SMsg( Msg : in Raw_Types.Serpent_Msg;
70 Counter : out Interfaces.Unsigned_16;
71 Keyset : out Serpent_Keyset) is
72 begin
73 -- check type id and call internal Read_SKeys if correct
74 if Msg(Msg'First) /= SKeys_S_Type then
75 raise Invalid_Msg;
76 else
77 Read_SKeys( Msg, Counter, Keyset );
78 end if;
79 end Read_SKeys_SMsg;
80
81 -- writes given key mgm structure into a Serpent message
82 procedure Write_KMgm_SMsg( KMgm : in Keys_Mgm;
83 Counter : in Interfaces.Unsigned_16;
84 Msg : out Raw_Types.Serpent_Msg) is
85 begin
86 -- call internal write of key mgm with correct type ID
87 Write_KMgm( KMgm, Counter, Key_Mgm_S_Type, Msg );
88 end Write_KMgm_SMsg;
89
90 -- reads a key mgm structure from the given Serpent message
91 procedure Read_KMgm_SMsg( Msg : in Raw_Types.Serpent_Msg;
92 Counter : out Interfaces.Unsigned_16;
93 KMgm : out Keys_Mgm) is
94 begin
95 -- check type id and call internal Read_KMgm if correct
96 if Msg(Msg'First) /= Key_Mgm_S_Type then
97 raise Invalid_Msg;
98 else
99 Read_KMgm( Msg, Counter, KMgm );
100 end if;
101 end Read_KMgm_SMsg;
102
103
104 ------------------
105 -- RSA Messages --
106 ------------------
107
108 procedure Write_SKeys_RMsg( Keyset : in Serpent_Keyset;
109 Counter : in Interfaces.Unsigned_16;
110 Msg : out Raw_Types.RSA_Msg) is
111 begin
112 -- call internal write of Serpent keys with correct type ID
113 Write_SKeys( Keyset, Counter, SKeys_R_Type, Msg );
114 end Write_SKeys_RMsg;
115
116 procedure Read_SKeys_RMsg( Msg : in Raw_Types.RSA_Msg;
117 Counter : out Interfaces.Unsigned_16;
118 Keyset : out Serpent_Keyset) is
119 begin
120 -- check type id and call internal Read_SKeys if correct
121 if Msg(Msg'First) /= SKeys_R_Type then
122 raise Invalid_Msg;
123 else
124 Read_SKeys( Msg, Counter, Keyset );
125 end if;
126 end Read_SKeys_RMsg;
127
128 procedure Write_KMgm_RMsg( KMgm : in Keys_Mgm;
129 Counter : in Interfaces.Unsigned_16;
130 Msg : out Raw_Types.RSA_Msg) is
131 begin
132 -- call internal write of key mgm with correct type ID
133 Write_KMgm( KMgm, Counter, Key_Mgm_R_Type, Msg );
134 end Write_KMgm_RMsg;
135
136 procedure Read_KMgm_RMsg( Msg : in Raw_Types.RSA_Msg;
137 Counter : out Interfaces.Unsigned_16;
138 KMgm : out Keys_Mgm) is
139 begin
140 -- check type id and call internal Read_KMgm if correct
141 if Msg(Msg'First) /= Key_Mgm_R_Type then
142 raise Invalid_Msg;
143 else
144 Read_KMgm( Msg, Counter, KMgm );
145 end if;
146 end Read_KMgm_RMsg;
147
148 ------------------
149 -- private part --
150 ------------------
151 procedure Cast_LE( LE: in out Raw_Types.Octets ) is
152 begin
153 -- flip octets ONLY if native is big endian.
154 if System.Default_Bit_Order = System.High_Order_First then
155 declare
156 BE: constant Raw_Types.Octets := LE;
157 begin
158 for I in 1..LE'Length loop
159 LE(LE'First+I-1) := BE(BE'Last-I+1);
160 end loop;
161 end;
162 end if;
163 -- NOTHING to do for native little endian
164 end Cast_LE;
165
166 procedure Write_SKeys( Keyset : in Serpent_Keyset;
167 Counter : in Interfaces.Unsigned_16;
168 Type_ID : in Interfaces.Unsigned_8;
169 Msg : out Raw_Types.Octets) is
170 Pos : Integer := Msg'First;
171 Check : CRC32.CRC32;
172 PadLen: Integer;
173 K : Serpent.Key;
174 begin
175 -- write Type ID
176 Msg(Pos) := SKeys_S_Type;
177 Msg(Pos) := Type_ID;
178 Pos := Pos + 1;
179
180 -- write count of keys (NB: this IS 8 bits by definition)
(60 . 17)(172 . 17)
182 Msg(Pos..Pos+PadLen-1) := Pad;
183 end;
184 end if;
185 end Write_SKeys_SMsg;
186
187 end Write_SKeys;
188
189 -- Reads a Serpent keyset from given Serpent Message
190 procedure Read_SKeys_SMsg( Msg : in Raw_Types.Serpent_Msg;
191 Counter : out Interfaces.Unsigned_16;
192 Keyset : out Serpent_Keyset) is
193 procedure Read_SKeys( Msg : in Raw_Types.Octets;
194 Counter : out Interfaces.Unsigned_16;
195 Keyset : out Serpent_Keyset) is
196 Pos: Integer := Msg'First;
197 begin
198 -- read type and check
199 if Msg(Pos) = SKeys_S_Type then
200 if Msg(Pos) = SKeys_S_Type or
201 Msg(Pos) = SKeys_R_Type then
202 Pos := Pos + 1;
203 else
204 raise Invalid_Msg;
(118 . 22)(230 . 100)
206 else
207 raise Invalid_Msg;
208 end if;
209 end Read_SKeys_SMsg;
210 end Read_SKeys;
211
212 -- private part
213 procedure Cast_LE( LE: in out Raw_Types.Octets ) is
214 -- writes given key management structure to the given octets array
215 procedure Write_KMgm( KMgm : in Keys_Mgm;
216 Counter : in Interfaces.Unsigned_16;
217 Type_ID : in Interfaces.Unsigned_8;
218 Msg : out Raw_Types.Octets) is
219 Pos : Integer := Msg'First;
220 begin
221 -- flip octets ONLY if native is big endian.
222 if System.Default_Bit_Order = System.High_Order_First then
223 declare
224 BE: constant Raw_Types.Octets := LE;
225 begin
226 for I in 1..LE'Length loop
227 LE(LE'First+I-1) := BE(BE'Last-I+1);
228 end loop;
229 end;
230 -- write given type id
231 Msg(Pos) := Type_ID;
232 Pos := Pos + 1;
233
234 -- write count of server keys requested
235 Msg(Pos) := KMgm.N_Server;
236 Pos := Pos + 1;
237
238 -- write count of client keys requested
239 Msg(Pos) := KMgm.N_Client;
240 Pos := Pos + 1;
241
242 -- write id of key preferred for further inbound Serpent messages
243 Msg(Pos) := KMgm.Key_ID;
244 Pos := Pos + 1;
245
246 -- write count of burnt keys in this message
247 Msg(Pos..Pos) := Cast( KMgm.N_Burnt );
248 Pos := Pos + 1;
249
250 -- if there are any burnt keys, write their ids
251 if KMgm.N_Burnt > 0 then
252 Msg( Pos .. Pos + KMgm.Burnt'Length - 1 ) := KMgm.Burnt;
253 Pos := Pos + KMgm.Burnt'Length;
254 end if;
255 -- NOTHING to do for native little endian
256 end Cast_LE;
257
258 -- write the message count
259 Msg(Pos..Pos+1) := Raw_Types.Cast( Counter );
260 Cast_LE( Msg(Pos..Pos+1) );
261 Pos := Pos + 2;
262
263 -- pad with random octets until the end of Msg
264 RNG.Get_Octets( Msg(Pos..Msg'Last) );
265
266 end Write_KMgm;
267
268 -- attempts to read from the given array of octets a key management structure
269 procedure Read_KMgm( Msg : in Raw_Types.Octets;
270 Counter : out Interfaces.Unsigned_16;
271 KMgm : out Keys_Mgm) is
272 Pos : Integer := Msg'First;
273 Burnt_Pos : Integer := Msg'First + 4;
274 begin
275 -- read type and check
276 if Msg(Pos) = Key_Mgm_S_Type or
277 Msg(Pos) = Key_Mgm_R_Type then
278 Pos := Pos + 1;
279 else
280 raise Invalid_Msg;
281 end if;
282
283 -- read the count of burnt keys and check
284 -- NB: Burnt_Pos IS in range of Counter_8bits since it's an octet
285 declare
286 N_Burnt : Counter_8bits := Counter_8bits(Msg(Burnt_Pos));
287 Mgm : Keys_Mgm(N_Burnt);
288 O2 : Raw_Types.Octets_2;
289 begin
290 -- read count of server keys requested
291 Mgm.N_Server := Msg(Pos);
292 Pos := Pos + 1;
293
294 -- read count of client keys requested
295 Mgm.N_Client := Msg(Pos);
296 Pos := Pos + 1;
297
298 -- read ID of Serpent key preferred for further inbound messages
299 Mgm.Key_ID := Msg(Pos);
300 Pos := Pos + 2; --skip the count of burnt keys as it's read already
301
302 -- read ids of burnt keys, if any
303 if N_Burnt > 0 then
304 Mgm.Burnt := Msg(Pos..Pos+N_Burnt-1);
305 Pos := Pos + N_Burnt;
306 end if;
307
308 -- read and set message counter
309 O2 := Msg(Pos..Pos+1);
310 Cast_LE(O2);
311 Counter := Raw_Types.Cast(O2);
312 -- rest of message is padding so it's ignored
313 -- copy the keys mgm structure to output param
314 KMgm := Mgm;
315 end;
316 end Read_KMgm;
317
318
319 end Messages;