-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhelper.ml
283 lines (244 loc) · 9.42 KB
/
helper.ml
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
open Ast
exception HelperError
(* [typ_eq t1 t2] returns [true] iff [t1] and [t2] are equal *)
let typ_eq (t1:labeltype) (t2:labeltype) : bool =
t1 = t2
let number_of_enclaves = 10
let get_src_content_type (t : labeltype) =
match t with
|(BtRef lt), p -> lt
| _ -> raise HelperError
let get_content_type (t : enclabeltype) =
match t with
|EBtRef(m, lt), p -> lt
| _ -> raise HelperError
let get_mode (t: enclabeltype) =
match t with
|EBtRef(m, lt), p -> m
|EBtFunc(m,_,p,u,_), q -> m
|EBtCond m, p -> m
| _ -> raise HelperError
let get_enc_precontext (t:enclabeltype) =
match t with
|EBtFunc(m,gencpre,p,u, gencpost), q -> gencpre
|_ -> raise HelperError
let get_enc_postcontext (t:enclabeltype) =
match t with
|EBtFunc(m,gencpre,p,u, gencpost), q -> gencpost
|_ -> raise HelperError
let get_src_precontext (t:labeltype) =
match t with
|BtFunc(gpre,p,u, gpost), q -> gpre
|_ -> raise HelperError
let get_src_postcontext (t:labeltype) =
match t with
|BtFunc(gpre,p,u, gpost), q -> gpost
|_ -> raise HelperError
let get_src_policy_lower_bound (t:labeltype) =
match t with
|BtFunc(gencpre,p,u, gencpost), q -> p
|_ -> raise HelperError
let get_enc_policy_lower_bound (t:enclabeltype) =
match t with
|EBtFunc(m,gencpre,p,u, gencpost), q -> p
|_ -> raise HelperError
(* Check if base types are same. Ignore policy for comparison
*)
let rec check_src_base_type b1 b2 = match (b1, b2) with
| BtRef lt1, BtRef lt2 -> check_src_base_type (fst lt1) (fst lt2)
| BtFunc (gpre1, p1, u1, gpost1), BtFunc (gpre2, p2, u2, gpost2) ->
let ispreequal = VarLocMap.equal (fun bp1 bp2 ->
begin match (bp1, bp2) with
|((b1, p1), (b2, p2)) ->
if (p1=p2) && (check_src_base_type b1 b2) then true
else false
| _ -> false
end) gpre1 gpre2 in
let ispostequal = VarLocMap.equal (fun bp1 bp2 ->
begin match (bp1, bp2) with
|((b1, p1), (b2, p2)) ->
if (p1=p2) && (check_src_base_type b1 b2) then true
else false
| _ -> false
end ) gpost1 gpost2 in
(* For functions lower bounds should be equal *)
(ispreequal && ispostequal && (p1 = p2) && (VarSet.equal u1 u2))
| BtInt, BtInt -> true
| BtBool, BtBool -> true
| BtCond, BtCond -> true
| _ ,_ -> false (* int, bool, cond *)
(* Check if base types are same. What about rho?
Ignore rho and policy for comparison
*)
let rec check_enc_base_type b1 b2 = match (b1, b2) with
| EBtRef (rho1, lt1), EBtRef (rho2, lt2) -> check_enc_base_type (fst lt1) (fst lt2)
| EBtFunc (rho1, gencpre1, p1, u1, gencpost1), EBtFunc (rho2, gencpre2, p2, u2, gencpost2) ->
let ispreequal = VarLocMap.equal (fun bp1 bp2 ->
begin match (bp1, bp2) with
|((b1, p1), (b2, p2)) ->
if (p1 =p2) && (check_enc_base_type b1 b2) then true
else false
| _ -> false
end) gencpre1 gencpre2 in
let ispostequal = VarLocMap.equal (fun bp1 bp2 ->
begin match (bp1, bp2) with
|((b1, p1), (b2, p2)) ->
if (p1=p2) && (check_enc_base_type b1 b2) then true
else false
| _ -> false
end ) gencpost1 gencpost2 in
(* For functions lower bounds should be equal *)
(ispreequal && ispostequal && (p1 = p2) && (VarSet.equal u1 u2))
| EBtInt, EBtInt -> true
| EBtBool, EBtBool -> true
| EBtCond rho1, EBtCond rho2 -> true
| _ ,_ -> false (* int, bool, cond *)
(* ---------- FRESH TYPE VARIABLES ---------- *)
let tvar_cell = ref 1
(* [next_tid ()] generates a fresh type variable *)
let next_tid () : var =
let x = !tvar_cell in
let s = "x" ^ string_of_int x in
incr tvar_cell; s
(* [next_tvar ()] generates a fresh type variable *)
let next_tvar () : mode =
let x = !tvar_cell in
let s = "x" ^ string_of_int x in
let _ = incr tvar_cell in
let newidvar = next_tid() in
ModeVar (s, newidvar)
let next_kvar() : var =
let x = !tvar_cell in
let s = "x" ^ string_of_int x in
let _ = incr tvar_cell in
s
let get_bij_var rho1 rho2 eidmap eidrevmap =
let (bij, eidmap', eidrevmap') = if EnclaveidRevMap.mem (rho1, rho2) eidrevmap then
(EnclaveidRevMap.find (rho1, rho2) eidrevmap, eidmap, eidrevmap)
else
let b12 = next_tid() in
let tempeidrevmap = EnclaveidRevMap.add (rho1, rho2) b12 eidrevmap in
(b12, EnclaveidMap.add b12 (rho1, rho2) eidmap, EnclaveidRevMap.add (rho1, rho2) b12 tempeidrevmap)
in
(bij, eidmap', eidrevmap')
(* Fulfil all combinations of bij *)
let rec fill_eidrevmap ms eidmap eidrevmap =
if not (ModeSet.is_empty ms) then
let rho = ModeSet.choose ms in
let ms' = ModeSet.remove rho ms in
(* Check if bij exists for each element of ms' *)
let rec check_bij ms eidmap eidrevmap =
if not (ModeSet.is_empty ms) then
let rho' = ModeSet.choose ms in
let ms' = ModeSet.remove rho' ms in
let (_, eidmap', eidrevmap') = get_bij_var rho rho' eidmap eidrevmap
in check_bij ms' eidmap' eidrevmap'
else
(eidmap, eidrevmap)
in
let (eidmap', eidrevmap') = check_bij ms' eidmap eidrevmap in
fill_eidrevmap ms' eidmap' eidrevmap'
else
(eidmap, eidrevmap)
let rec countCondConstraints (c:constr2) =
let rec outerloop c2 num_constraints =
let a, b = Constr2.choose c2 in
let c2' = Constr2.remove (a,b) c2 in
let constraints_per_row = 1 in
let totalconstraints = constraints_per_row + num_constraints in
if (Constr2.is_empty c2') then totalconstraints else outerloop c2' totalconstraints
in
if (Constr2.is_empty c) then 0 else outerloop c 0
(* -----------UPDATE CONSTRAINTS ------------*)
let rec update_constraints (t: (mode * mode) list) (c:constr) eidmap eidrevmap =
match t with
| [] -> (c, eidmap, eidrevmap)
| (rho1, rho2)::ts -> let c' = (Constr.add (Modecond (rho1, rho2)) c) in
let (bij, eidmap1, eidrevmap1) = get_bij_var rho1 rho2 eidmap eidrevmap in
update_constraints ts (Constr.add (Eidcond (bij, 0)) c') eidmap1 eidrevmap1
let rec add_bij_equiv_constraints eidmap eidrevmap c =
let (bij, (rhoi, rhoj)) = EnclaveidMap.choose eidmap in
let eidmap' = EnclaveidMap.remove bij eidmap in
if not (EnclaveidMap.is_empty eidmap') then
(* Find all bindings where fst(key) or snd(key) = rhoj *)
let eidrevmapj = EnclaveidRevMap.filter (fun key a -> if ((fst key) = rhoj && (not ((snd key) = rhoi))) ||
((not ((fst key) = rhoi)) && (snd key) = rhoj) then true
else false ) eidrevmap
in
let bindinglist = EnclaveidRevMap.bindings eidrevmapj in
let rec update_bij_constraints c blist =
match blist with
|[] -> c
|((rho1, rho2), bjk)::tail -> let rhok = if (rho1 = rhoj) then rho2 else rho1 in
(* find if a binding exists for (rhoi, rhok) and get bik *)
(* Note that eidmap/eidrevmap cannot get updated because we filled it before *)
let (bik, _, _) = get_bij_var rhoi rhok eidmap eidrevmap in
(* Update Constraints bij = 0 /\ bjk = 0 -> bik =0 *)
let c' = Constr2.add (Preeidcond ((bij, 0), (bjk, 0)), Eidcond (bik, 0)) c in
(* Update Constraints bij = 1 /\ bjk = 0 -> bik =1 *)
let c'' = Constr2.add (Preeidcond ((bij, 1), (bjk, 0)), Eidcond (bik, 1)) c' in
update_bij_constraints c'' tail
in
let c' = update_bij_constraints c bindinglist in
(* Find all bindings where fst(key) or snd(key) = rhoi *)
let eidrevmapi = EnclaveidRevMap.filter (fun key a -> if ((fst key) = rhoi && (not ((snd key) = rhoj))) ||
((not ((fst key) = rhoj)) && (snd key) = rhoi) then true
else false ) eidrevmap
in
let bindinglisti = EnclaveidRevMap.bindings eidrevmapi in
let rec update_bji_constraints c blist =
match blist with
|[] -> c
|((rho1, rho2), bik)::tail -> let rhok = if (rho1 = rhoi) then rho2 else rho1 in
(* find if a binding exists for (rhoj, rhok) and get bjk *)
let (bjk, _, _) = get_bij_var rhoj rhok eidmap eidrevmap in
(* Update Constraints bij = 0 /\ bik = 0 -> bjk =0 *)
let c' = Constr2.add (Preeidcond ((bij, 0), (bik, 0)), Eidcond (bjk, 0)) c in
(* Update Constraints bij = 1 /\ bik = 0 -> bjk =1 *)
let c'' = Constr2.add (Preeidcond ((bij, 1), (bik, 0)), Eidcond (bjk, 1)) c' in
update_bij_constraints c'' tail
in
let c'' = update_bji_constraints c' bindinglisti in
add_bij_equiv_constraints eidmap' eidrevmap c''
else
c
(* ------- Flatten Sequence ------------ *)
let rec flattenseq s = match s with
|Seq(c1, c2) -> flattenseq c1 @ flattenseq c2
| _ -> [s]
let getexpmode = function
| EVar(rho, v) -> rho
| ELam(rho, rho', gpre, p, u, q, gpost, s) -> rho
| EPlus (rho, l,r) -> rho
| EConstant(rho,n) -> rho
| ETrue rho -> rho
| EFalse rho -> rho
| EEq (rho, l,r) -> rho
| ELoc(rho, rho', l) ->rho
| EDeref(rho,e) -> rho
| EIsunset(rho,x) -> rho
let getstmtmode = function
| EIf (m,e,c1,c2,_) -> m
| EAssign(m, x, e,_) ->m
| EDeclassify(m, x, e,_) ->m
| ESeq(m,s1, s2,_) -> m
| ECall(m,e,_) -> m
| EUpdate(m,e1, e2,_) ->m
| EWhile(m, b, s,_) -> m
| ESkip (m, m',_) -> m'
| EOutput(m,ch, e,_) ->m
| ESet(m,x,_) -> m
| EESeq (m, _,_) -> m
let getrhovar = function
| ModeVar(x, _) -> x
| _ -> raise HelperError
(* -----------Typing Context Checks ---------- *)
(* Returns true when all registers all low *)
let check_typing_context_reg_low (genc1:enccontext) =
VarLocMap.for_all (fun key value -> begin match key with
| Reg x -> begin match (snd value) with
| Low -> true
| _ -> false
end
| _ -> true
end) genc1