-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmilNoninterferenceScript.sml
309 lines (256 loc) · 10.3 KB
/
milNoninterferenceScript.sml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
open HolKernel boolLib bossLib listTheory pairTheory relationTheory bisimulationTheory milTheory milMetaTheory milTracesTheory milUtilityTheory;
(* ================================================ *)
(* MIL conditional noninterference and bisimulation *)
(* ================================================ *)
val _ = new_theory "milNoninterference";
(* Definition of out-of-order step with value-independent labels *)
Definition out_of_order_step':
(out_of_order_step' S (l_lb obs (act_cmt a v) t) S' =
((v = 0w) /\ ?v. out_of_order_step S (l_lb obs (act_cmt a v) t) S')) /\
(out_of_order_step' S l S' = out_of_order_step S l S')
End
(* Definition of in-order step with value-independent labels *)
Definition in_order_step':
(in_order_step' S (l_lb obs (act_cmt a v) t) S' =
((v = 0w) /\ ?v. in_order_step S (l_lb obs (act_cmt a v) t) S')) /\
(in_order_step' S l S' = in_order_step S l S')
End
(* Definition of trace indistinguishability
NOTE: we fix two parameters of trace: obs_of_label = obs_of_l, visible = obs_visible *)
Definition trace_indist:
trace_indist step S1 S2 =
((!pi1. step_execution step pi1 ==> FST (HD pi1) = S1 ==>
?pi2. step_execution step pi2 /\ FST (HD pi2) = S2 /\
trace obs_of_l obs_visible pi1 = trace obs_of_l obs_visible pi2) /\
(!pi2. step_execution step pi2 ==> FST (HD pi2) = S2 ==>
?pi1. step_execution step pi1 /\ FST (HD pi1) = S1 /\
trace obs_of_l obs_visible pi1 = trace obs_of_l obs_visible pi2))
End
Definition trace_indist_IO:
trace_indist_IO = trace_indist in_order_step'
End
Definition trace_indist_OoO:
trace_indist_OoO = trace_indist out_of_order_step'
End
Theorem trace_indist_is_symmetric:
! step. symmetric (trace_indist step)
Proof
rw [trace_indist, symmetric_def] >>
EQ_TAC >> METIS_TAC []
QED
Theorem trace_indist_IO_is_symmetric:
symmetric trace_indist_IO
Proof
rw [trace_indist_IO, trace_indist_is_symmetric]
QED
Theorem trace_indist_OoO_is_symmetric:
symmetric trace_indist_OoO
Proof
rw [trace_indist_OoO, trace_indist_is_symmetric]
QED
(* Definition of MIL noninterference
NOTE: secpol is not required to be an equivalence *)
Definition NI:
NI step_p secpol =
(!S1 S2. secpol S1 S2 ==> trace_indist step_p S1 S2)
End
Definition NI_IO:
NI_IO = NI in_order_step'
End
Definition NI_OoO:
NI_OoO = NI out_of_order_step'
End
(* Definition of MIL conditional noninterference
NOTE: secpol is not required to be an equivalence *)
Definition CNI:
CNI step_r step_t secpol =
(!S1 S2. secpol S1 S2 ==> trace_indist step_r S1 S2 ==> trace_indist step_t S1 S2)
End
Definition CNI_IO_OoO:
CNI_IO_OoO = CNI in_order_step' out_of_order_step'
End
Theorem NI_implies_CNI:
! secpol step_r step_t .
NI step_t secpol ==> CNI step_r step_t secpol
Proof
rw [NI, CNI]
QED
Theorem NI_OoO_implies_CNI_IO_OoO:
! secpol . NI_OoO secpol ==> CNI_IO_OoO secpol
Proof
rw [NI_OoO, CNI_IO_OoO, NI, CNI]
QED
(* Lemma: bisimulation implies trace indistinguishability in OoO *)
Theorem BISIM_implies_trace_indist_OoO:
! S1 S2 .
(?R. BISIM out_of_order_step' R /\ R S1 S2 /\ symmetric R) ==> trace_indist_OoO S1 S2
Proof
rw [trace_indist_OoO] >>
REWRITE_TAC [trace_indist] >>
fs [BISIM_def] >>
Q.ABBREV_TAC `step = out_of_order_step'` >>
`(! pi1 . step_execution step pi1 ==> FST (HD pi1) = S1 ==>
? pi2 . step_execution step pi2 /\ FST (HD pi2) = S2 /\
trace obs_of_l obs_visible pi1 = trace obs_of_l obs_visible pi2 /\
R ((SND o SND) (LAST pi1)) ((SND o SND) (LAST pi2))) /\
(! pi2 . step_execution step pi2 ==> FST (HD pi2) = S2 ==>
? pi1 . step_execution step pi1 /\ FST (HD pi1) = S1 /\
trace obs_of_l obs_visible pi1 = trace obs_of_l obs_visible pi2 /\
R ((SND o SND) (LAST pi2)) ((SND o SND) (LAST pi1)))`
suffices_by METIS_TAC [] >>
rw [] >| [
Induct_on `pi1` using SNOC_INDUCT >| [
(* impossible case: an execution is never empty *)
METIS_TAC [step_execution_not_empty_list],
Induct_on `pi1` using SNOC_INDUCT >>
rw [] >| [
(* base case: singleton execution *)
Cases_on `x` >> Cases_on `r` >>
rename1 `(S1, lb, S1')` >>
`step S1 lb S1'`
by fs [step_execution_single] >>
`R S1 S2`
by fs [] >>
Cases_on `lb` >>
rename1 `l_lb obs act t` >>
`? S2' . step S2 (l_lb obs act t) S2' /\ R S1' S2'`
by METIS_TAC [] >>
(* there exists pi2 *)
Q.EXISTS_TAC `[(S2, l_lb obs act t, S2')]` >>
rw [] >| [
METIS_TAC [step_execution_cases],
fs [trace]
],
(* inductive case *)
Cases_on `x` >> Cases_on `r` >>
Cases_on `x'` >> Cases_on `r` >>
rename1 `SNOC (Sp1'', l1'', S1'') (SNOC (Sp1', l1', S1') pi1)` >>
`step_execution step (pi1 ++ [(Sp1', l1', S1'); (Sp1'', l1'', S1'')])`
by fs [SNOC_APPEND, APPEND_CONS] >>
(* premise 1 for applying IH *)
Q.ABBREV_TAC `S1 = FST (HD (SNOC (Sp1', l1', S1') pi1))` >>
`S1 = FST (HD (SNOC (Sp1'', l1'', S1'') (SNOC (Sp1', l1', S1') pi1)))`
by fs [HD_APPEND_reduce, SNOC_APPEND] >>
`R (FST (HD (SNOC (Sp1', l1', S1') pi1))) S2`
by fs [] >>
(* premise 2 for applying IH *)
`step_execution step (pi1 ++ [(Sp1', l1', S1')])`
by METIS_TAC [step_execution_rest] >>
(* premise 1 for applying one-step bisimulation *)
`step Sp1'' l1'' S1''`
by METIS_TAC [step_execution_rest] >>
`S1' = Sp1''`
by METIS_TAC [step_execution_append_eq_state_base] >>
`step S1' l1'' S1''`
by fs [] >>
(* by IH, we get another premise for applying one-step bisimulation *)
`? pi2. FST (HD pi2) = S2 /\ step_execution step pi2 /\
trace obs_of_l obs_visible (SNOC (Sp1', l1', S1') pi1) =
trace obs_of_l obs_visible pi2 /\
R S1' ((SND o SND) (LAST pi2))`
by METIS_TAC [SNOC_APPEND, LAST_SNOC, combinTheory.o_THM, SND] >>
Q.ABBREV_TAC `S2' = (SND o SND) (LAST pi2)` >>
(* now we have:
- R S1' S2'
- step S1' l1'' S1''
apply one-step bisimulation to extend pi2 with: S2' -l1''-> S2''
*)
Cases_on `l1''` >>
rename1 `l_lb obs act t` >>
`? S2'' . step S2' (l_lb obs act t) S2'' /\ R S1'' S2''`
by METIS_TAC [] >>
(* there exists an extended pi2 *)
Q.EXISTS_TAC `pi2 ++ [(S2', l_lb obs act t, S2'')]` >>
rw [] >| [
(* extended pi2 is still an execution *)
fs [step_execution_append_one],
(* initial state of pi2 is still S2 *)
`pi2 <> []` by METIS_TAC [step_execution_not_empty_list] >>
fs [HD_APPEND_reduce],
(* extended pi2 still has the same trace as extended pi1 *)
`trace obs_of_l obs_visible (pi1 ++ [(Sp1', l1', S1')] ++ [(S1', l_lb obs act t, S1'')]) =
trace obs_of_l obs_visible (pi2 ++ [(S2', l_lb obs act t, S2'')])`
by fs [trace_append_eq_label] >>
fs []
]
]
],
Induct_on `pi2` using SNOC_INDUCT >| [
METIS_TAC [step_execution_not_empty_list],
Induct_on `pi2` using SNOC_INDUCT >>
rw [] >| [
Cases_on `x` >> Cases_on `r` >>
rename1 `(S2, lb, S2')` >>
`step S2 lb S2'`
by fs [step_execution_single] >>
`R S2 S1` (* R should be symmetric! *)
by fs [symmetric_def] >>
Cases_on `lb` >>
rename1 `l_lb obs act t` >>
`? S1' . step S1 (l_lb obs act t) S1' /\ R S2' S1'`
by METIS_TAC [] >>
Q.EXISTS_TAC `[(S1, l_lb obs act t, S1')]` >>
rw [] >| [
METIS_TAC [step_execution_cases],
fs [trace]
],
Cases_on `x` >> Cases_on `r` >>
Cases_on `x'` >> Cases_on `r` >>
rename1 `SNOC (Sp2'', l2'', S2'') (SNOC (Sp2', l2', S2') pi2)` >>
`step_execution step (pi2 ++ [(Sp2', l2', S2'); (Sp2'', l2'', S2'')])`
by fs [SNOC_APPEND, APPEND_CONS] >>
Q.ABBREV_TAC `S2 = FST (HD (SNOC (Sp2', l2', S2') pi2))` >>
`S2 = FST (HD (SNOC (Sp2'', l2'', S2'') (SNOC (Sp2', l2', S2') pi2)))`
by fs [HD_APPEND_reduce, SNOC_APPEND] >>
`R S1 (FST (HD (SNOC (Sp2', l2', S2') pi2)))`
by fs [] >>
`step_execution step (pi2 ++ [(Sp2', l2', S2')])`
by METIS_TAC [step_execution_rest] >>
`step Sp2'' l2'' S2''`
by METIS_TAC [step_execution_rest] >>
`S2' = Sp2''`
by METIS_TAC [step_execution_append_eq_state_base] >>
`step S2' l2'' S2''`
by fs [] >>
`? pi1. FST (HD pi1) = S1 /\ step_execution step pi1 /\
trace obs_of_l obs_visible (SNOC (Sp2', l2', S2') pi2) =
trace obs_of_l obs_visible pi1 /\
R S2' ((SND o SND) (LAST pi1))`
by METIS_TAC [SNOC_APPEND, LAST_SNOC, combinTheory.o_THM, SND] >>
Q.ABBREV_TAC `S1' = (SND o SND) (LAST pi1)` >>
Cases_on `l2''` >>
rename1 `l_lb obs act t` >>
`? S1'' . step S1' (l_lb obs act t) S1'' /\ R S2'' S1''`
by METIS_TAC [] >>
Q.EXISTS_TAC `pi1 ++ [(S1', l_lb obs act t, S1'')]` >>
rw [] >| [
fs [step_execution_append_one],
`pi1 <> []` by METIS_TAC [step_execution_not_empty_list] >>
fs [HD_APPEND_reduce],
`trace obs_of_l obs_visible (pi2 ++ [(Sp2', l2', S2')] ++ [(S2', l_lb obs act t, S2'')]) =
trace obs_of_l obs_visible (pi1 ++ [(S1', l_lb obs act t, S1'')])`
by fs [trace_append_eq_label] >>
fs []
]
]
]
]
QED
(* Lemma: MIL conditional noninterference reduction *)
Theorem CNI_reduction:
! secpol .
(? L R .
(!S1 S2. secpol S1 S2 ==> trace_indist_IO S1 S2 ==> L S1 S2) /\
BISIM out_of_order_step' R /\
(!S1 S2. secpol S1 S2 ==> L S1 S2 ==> R S1 S2)) ==>
CNI_IO_OoO secpol
Proof
rw [CNI_IO_OoO, CNI, trace_indist_IO] >>
`BISIM out_of_order_step' (R RUNION inv R)`
by fs [BISIM_RUNION, BISIM_INV] >>
Q.ABBREV_TAC `R' = R RUNION inv R` >>
`R' S1 S2` by METIS_TAC [RUNION] >>
`symmetric R'` by METIS_TAC [RUNION, inv_DEF, symmetric_def] >>
METIS_TAC [BISIM_implies_trace_indist_OoO, trace_indist_OoO]
QED
val _ = export_theory ();