25 AddDs [impOfSubs Fake_parts_insert]; |
25 AddDs [impOfSubs Fake_parts_insert]; |
26 |
26 |
27 |
27 |
28 (*A "possibility property": there are traces that reach the end*) |
28 (*A "possibility property": there are traces that reach the end*) |
29 Goal |
29 Goal |
30 "!!A B. [| A ~= B; A ~= Server; B ~= Server |] \ |
30 "[| A ~= B; A ~= Server; B ~= Server |] \ |
31 \ ==> EX K. EX NA. EX evs: otway. \ |
31 \ ==> EX K. EX NA. EX evs: otway. \ |
32 \ Says B A {|Nonce NA, Crypt (shrK A) {|Nonce NA, Key K|}|} \ |
32 \ Says B A {|Nonce NA, Crypt (shrK A) {|Nonce NA, Key K|}|} \ |
33 \ : set evs"; |
33 \ : set evs"; |
34 by (REPEAT (resolve_tac [exI,bexI] 1)); |
34 by (REPEAT (resolve_tac [exI,bexI] 1)); |
35 by (rtac (otway.Nil RS otway.OR1 RS otway.OR2 RS otway.OR3 RS otway.OR4) 2); |
35 by (rtac (otway.Nil RS otway.OR1 RS otway.OR2 RS otway.OR3 RS otway.OR4) 2); |
36 by possibility_tac; |
36 by possibility_tac; |
37 result(); |
37 result(); |
38 |
38 |
39 |
39 |
40 (**** Inductive proofs about otway ****) |
40 (**** Inductive proofs about otway ****) |
41 |
41 |
42 (*Nobody sends themselves messages*) |
42 (*Nobody sends themselves messages*) |
43 Goal "!!evs. evs : otway ==> ALL A X. Says A A X ~: set evs"; |
43 Goal "evs : otway ==> ALL A X. Says A A X ~: set evs"; |
44 by (etac otway.induct 1); |
44 by (etac otway.induct 1); |
45 by Auto_tac; |
45 by Auto_tac; |
46 qed_spec_mp "not_Says_to_self"; |
46 qed_spec_mp "not_Says_to_self"; |
47 Addsimps [not_Says_to_self]; |
47 Addsimps [not_Says_to_self]; |
48 AddSEs [not_Says_to_self RSN (2, rev_notE)]; |
48 AddSEs [not_Says_to_self RSN (2, rev_notE)]; |
49 |
49 |
50 |
50 |
51 (** For reasoning about the encrypted portion of messages **) |
51 (** For reasoning about the encrypted portion of messages **) |
52 |
52 |
53 Goal "!!evs. Says A' B {|N, Agent A, Agent B, X|} : set evs \ |
53 Goal "Says A' B {|N, Agent A, Agent B, X|} : set evs \ |
54 \ ==> X : analz (spies evs)"; |
54 \ ==> X : analz (spies evs)"; |
55 by (dtac (Says_imp_spies RS analz.Inj) 1); |
55 by (dtac (Says_imp_spies RS analz.Inj) 1); |
56 by (Blast_tac 1); |
56 by (Blast_tac 1); |
57 qed "OR2_analz_spies"; |
57 qed "OR2_analz_spies"; |
58 |
58 |
59 Goal "!!evs. Says S' B {|N, X, Crypt (shrK B) X'|} : set evs \ |
59 Goal "Says S' B {|N, X, Crypt (shrK B) X'|} : set evs \ |
60 \ ==> X : analz (spies evs)"; |
60 \ ==> X : analz (spies evs)"; |
61 by (dtac (Says_imp_spies RS analz.Inj) 1); |
61 by (dtac (Says_imp_spies RS analz.Inj) 1); |
62 by (Blast_tac 1); |
62 by (Blast_tac 1); |
63 qed "OR4_analz_spies"; |
63 qed "OR4_analz_spies"; |
64 |
64 |
65 Goal "!!evs. Says Server B {|NA, X, Crypt K' {|NB,K|}|} : set evs \ |
65 Goal "Says Server B {|NA, X, Crypt K' {|NB,K|}|} : set evs \ |
66 \ ==> K : parts (spies evs)"; |
66 \ ==> K : parts (spies evs)"; |
67 by (Blast_tac 1); |
67 by (Blast_tac 1); |
68 qed "Oops_parts_spies"; |
68 qed "Oops_parts_spies"; |
69 |
69 |
70 bind_thm ("OR2_parts_spies", |
70 bind_thm ("OR2_parts_spies", |
71 OR2_analz_spies RS (impOfSubs analz_subset_parts)); |
71 OR2_analz_spies RS (impOfSubs analz_subset_parts)); |
83 |
83 |
84 (** Theorems of the form X ~: parts (spies evs) imply that NOBODY |
84 (** Theorems of the form X ~: parts (spies evs) imply that NOBODY |
85 sends messages containing X! **) |
85 sends messages containing X! **) |
86 |
86 |
87 (*Spy never sees a good agent's shared key!*) |
87 (*Spy never sees a good agent's shared key!*) |
88 Goal |
88 Goal "evs : otway ==> (Key (shrK A) : parts (spies evs)) = (A : bad)"; |
89 "!!evs. evs : otway ==> (Key (shrK A) : parts (spies evs)) = (A : bad)"; |
|
90 by (parts_induct_tac 1); |
89 by (parts_induct_tac 1); |
91 by (ALLGOALS Blast_tac); |
90 by (ALLGOALS Blast_tac); |
92 qed "Spy_see_shrK"; |
91 qed "Spy_see_shrK"; |
93 Addsimps [Spy_see_shrK]; |
92 Addsimps [Spy_see_shrK]; |
94 |
93 |
95 Goal |
94 Goal "evs : otway ==> (Key (shrK A) : analz (spies evs)) = (A : bad)"; |
96 "!!evs. evs : otway ==> (Key (shrK A) : analz (spies evs)) = (A : bad)"; |
|
97 by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset())); |
95 by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset())); |
98 qed "Spy_analz_shrK"; |
96 qed "Spy_analz_shrK"; |
99 Addsimps [Spy_analz_shrK]; |
97 Addsimps [Spy_analz_shrK]; |
100 |
98 |
101 AddSDs [Spy_see_shrK RSN (2, rev_iffD1), |
99 AddSDs [Spy_see_shrK RSN (2, rev_iffD1), |
102 Spy_analz_shrK RSN (2, rev_iffD1)]; |
100 Spy_analz_shrK RSN (2, rev_iffD1)]; |
103 |
101 |
104 |
102 |
105 (*Nobody can have used non-existent keys!*) |
103 (*Nobody can have used non-existent keys!*) |
106 Goal "!!evs. evs : otway ==> \ |
104 Goal "evs : otway ==> Key K ~: used evs --> K ~: keysFor (parts (spies evs))"; |
107 \ Key K ~: used evs --> K ~: keysFor (parts (spies evs))"; |
|
108 by (parts_induct_tac 1); |
105 by (parts_induct_tac 1); |
109 (*Fake*) |
106 (*Fake*) |
110 by (blast_tac (claset() addSDs [keysFor_parts_insert]) 1); |
107 by (blast_tac (claset() addSDs [keysFor_parts_insert]) 1); |
111 (*OR2, OR3*) |
108 (*OR2, OR3*) |
112 by (ALLGOALS Blast_tac); |
109 by (ALLGOALS Blast_tac); |
122 |
119 |
123 (*** Proofs involving analz ***) |
120 (*** Proofs involving analz ***) |
124 |
121 |
125 (*Describes the form of K and NA when the Server sends this message. Also |
122 (*Describes the form of K and NA when the Server sends this message. Also |
126 for Oops case.*) |
123 for Oops case.*) |
127 Goal |
124 Goal "[| Says Server B {|NA, X, Crypt (shrK B) {|NB, Key K|}|} : set evs; \ |
128 "!!evs. [| Says Server B {|NA, X, Crypt (shrK B) {|NB, Key K|}|} : set evs; \ |
125 \ evs : otway |] \ |
129 \ evs : otway |] \ |
126 \ ==> K ~: range shrK & (EX i. NA = Nonce i) & (EX j. NB = Nonce j)"; |
130 \ ==> K ~: range shrK & (EX i. NA = Nonce i) & (EX j. NB = Nonce j)"; |
|
131 by (etac rev_mp 1); |
127 by (etac rev_mp 1); |
132 by (etac otway.induct 1); |
128 by (etac otway.induct 1); |
133 by (ALLGOALS Simp_tac); |
129 by (ALLGOALS Simp_tac); |
134 by (ALLGOALS Blast_tac); |
130 by (ALLGOALS Blast_tac); |
135 qed "Says_Server_message_form"; |
131 qed "Says_Server_message_form"; |
154 |
150 |
155 |
151 |
156 (** Session keys are not used to encrypt other session keys **) |
152 (** Session keys are not used to encrypt other session keys **) |
157 |
153 |
158 (*The equality makes the induction hypothesis easier to apply*) |
154 (*The equality makes the induction hypothesis easier to apply*) |
159 Goal |
155 Goal "evs : otway ==> \ |
160 "!!evs. evs : otway ==> \ |
156 \ ALL K KK. KK <= Compl (range shrK) --> \ |
161 \ ALL K KK. KK <= Compl (range shrK) --> \ |
157 \ (Key K : analz (Key``KK Un (spies evs))) = \ |
162 \ (Key K : analz (Key``KK Un (spies evs))) = \ |
158 \ (K : KK | Key K : analz (spies evs))"; |
163 \ (K : KK | Key K : analz (spies evs))"; |
|
164 by (etac otway.induct 1); |
159 by (etac otway.induct 1); |
165 by analz_spies_tac; |
160 by analz_spies_tac; |
166 by (REPEAT_FIRST (resolve_tac [allI, impI])); |
161 by (REPEAT_FIRST (resolve_tac [allI, impI])); |
167 by (REPEAT_FIRST (rtac analz_image_freshK_lemma )); |
162 by (REPEAT_FIRST (rtac analz_image_freshK_lemma )); |
168 by (ALLGOALS (asm_simp_tac analz_image_freshK_ss)); |
163 by (ALLGOALS (asm_simp_tac analz_image_freshK_ss)); |
169 (*Fake*) |
164 (*Fake*) |
170 by (spy_analz_tac 1); |
165 by (spy_analz_tac 1); |
171 qed_spec_mp "analz_image_freshK"; |
166 qed_spec_mp "analz_image_freshK"; |
172 |
167 |
173 |
168 |
174 Goal |
169 Goal "[| evs : otway; KAB ~: range shrK |] ==> \ |
175 "!!evs. [| evs : otway; KAB ~: range shrK |] ==> \ |
170 \ Key K : analz (insert (Key KAB) (spies evs)) = \ |
176 \ Key K : analz (insert (Key KAB) (spies evs)) = \ |
171 \ (K = KAB | Key K : analz (spies evs))"; |
177 \ (K = KAB | Key K : analz (spies evs))"; |
|
178 by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1); |
172 by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1); |
179 qed "analz_insert_freshK"; |
173 qed "analz_insert_freshK"; |
180 |
174 |
181 |
175 |
182 (*** The Key K uniquely identifies the Server's message. **) |
176 (*** The Key K uniquely identifies the Server's message. **) |
183 |
177 |
184 Goal |
178 Goal "evs : otway ==> \ |
185 "!!evs. evs : otway ==> \ |
179 \ EX B' NA' NB' X'. ALL B NA NB X. \ |
186 \ EX B' NA' NB' X'. ALL B NA NB X. \ |
|
187 \ Says Server B {|NA, X, Crypt (shrK B) {|NB, K|}|} : set evs --> \ |
180 \ Says Server B {|NA, X, Crypt (shrK B) {|NB, K|}|} : set evs --> \ |
188 \ B=B' & NA=NA' & NB=NB' & X=X'"; |
181 \ B=B' & NA=NA' & NB=NB' & X=X'"; |
189 by (etac otway.induct 1); |
182 by (etac otway.induct 1); |
190 by (ALLGOALS (asm_simp_tac (simpset() addsimps [all_conj_distrib]))); |
183 by (ALLGOALS (asm_simp_tac (simpset() addsimps [all_conj_distrib]))); |
191 by (ALLGOALS Clarify_tac); |
184 by (ALLGOALS Clarify_tac); |
196 by (REPEAT (ares_tac [refl,exI,impI,conjI] 2)); |
189 by (REPEAT (ares_tac [refl,exI,impI,conjI] 2)); |
197 (*...we assume X is a recent message, and handle this case by contradiction*) |
190 (*...we assume X is a recent message, and handle this case by contradiction*) |
198 by (blast_tac (claset() addSEs spies_partsEs) 1); |
191 by (blast_tac (claset() addSEs spies_partsEs) 1); |
199 val lemma = result(); |
192 val lemma = result(); |
200 |
193 |
201 Goal |
194 Goal "[| Says Server B {|NA, X, Crypt (shrK B) {|NB, K|}|} : set evs; \ |
202 "!!evs. [| Says Server B {|NA, X, Crypt (shrK B) {|NB, K|}|} : set evs; \ |
195 \ Says Server B' {|NA',X',Crypt (shrK B') {|NB',K|}|} : set evs; \ |
203 \ Says Server B' {|NA',X',Crypt (shrK B') {|NB',K|}|} : set evs; \ |
196 \ evs : otway |] ==> X=X' & B=B' & NA=NA' & NB=NB'"; |
204 \ evs : otway |] ==> X=X' & B=B' & NA=NA' & NB=NB'"; |
|
205 by (prove_unique_tac lemma 1); |
197 by (prove_unique_tac lemma 1); |
206 qed "unique_session_keys"; |
198 qed "unique_session_keys"; |
207 |
199 |
208 |
200 |
209 (** Crucial secrecy property: Spy does not see the keys sent in msg OR3 |
201 (** Crucial secrecy property: Spy does not see the keys sent in msg OR3 |
210 Does not in itself guarantee security: an attack could violate |
202 Does not in itself guarantee security: an attack could violate |
211 the premises, e.g. by having A=Spy **) |
203 the premises, e.g. by having A=Spy **) |
212 |
204 |
213 Goal |
205 Goal "[| A ~: bad; B ~: bad; evs : otway |] \ |
214 "!!evs. [| A ~: bad; B ~: bad; evs : otway |] \ |
206 \ ==> Says Server B \ |
215 \ ==> Says Server B \ |
207 \ {|NA, Crypt (shrK A) {|NA, Key K|}, \ |
216 \ {|NA, Crypt (shrK A) {|NA, Key K|}, \ |
208 \ Crypt (shrK B) {|NB, Key K|}|} : set evs --> \ |
217 \ Crypt (shrK B) {|NB, Key K|}|} : set evs --> \ |
209 \ Notes Spy {|NA, NB, Key K|} ~: set evs --> \ |
218 \ Notes Spy {|NA, NB, Key K|} ~: set evs --> \ |
210 \ Key K ~: analz (spies evs)"; |
219 \ Key K ~: analz (spies evs)"; |
|
220 by (etac otway.induct 1); |
211 by (etac otway.induct 1); |
221 by analz_spies_tac; |
212 by analz_spies_tac; |
222 by (ALLGOALS |
213 by (ALLGOALS |
223 (asm_simp_tac (simpset() addcongs [conj_cong] |
214 (asm_simp_tac (simpset() addcongs [conj_cong] |
224 addsimps [analz_insert_eq, analz_insert_freshK] |
215 addsimps [analz_insert_eq, analz_insert_freshK] |
231 by (Blast_tac 2); |
222 by (Blast_tac 2); |
232 (*Fake*) |
223 (*Fake*) |
233 by (spy_analz_tac 1); |
224 by (spy_analz_tac 1); |
234 val lemma = result() RS mp RS mp RSN(2,rev_notE); |
225 val lemma = result() RS mp RS mp RSN(2,rev_notE); |
235 |
226 |
236 Goal |
227 Goal "[| Says Server B \ |
237 "!!evs. [| Says Server B \ |
228 \ {|NA, Crypt (shrK A) {|NA, Key K|}, \ |
238 \ {|NA, Crypt (shrK A) {|NA, Key K|}, \ |
229 \ Crypt (shrK B) {|NB, Key K|}|} : set evs; \ |
239 \ Crypt (shrK B) {|NB, Key K|}|} : set evs; \ |
230 \ Notes Spy {|NA, NB, Key K|} ~: set evs; \ |
240 \ Notes Spy {|NA, NB, Key K|} ~: set evs; \ |
231 \ A ~: bad; B ~: bad; evs : otway |] \ |
241 \ A ~: bad; B ~: bad; evs : otway |] \ |
232 \ ==> Key K ~: analz (spies evs)"; |
242 \ ==> Key K ~: analz (spies evs)"; |
|
243 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1); |
233 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1); |
244 by (blast_tac (claset() addSEs [lemma]) 1); |
234 by (blast_tac (claset() addSEs [lemma]) 1); |
245 qed "Spy_not_see_encrypted_key"; |
235 qed "Spy_not_see_encrypted_key"; |
246 |
236 |
247 |
237 |
249 |
239 |
250 (*Only OR1 can have caused such a part of a message to appear. |
240 (*Only OR1 can have caused such a part of a message to appear. |
251 I'm not sure why A ~= B premise is needed: OtwayRees.ML doesn't need it. |
241 I'm not sure why A ~= B premise is needed: OtwayRees.ML doesn't need it. |
252 Perhaps it's because OR2 has two similar-looking encrypted messages in |
242 Perhaps it's because OR2 has two similar-looking encrypted messages in |
253 this version.*) |
243 this version.*) |
254 Goal |
244 Goal "[| A ~: bad; A ~= B; evs : otway |] \ |
255 "!!evs. [| A ~: bad; A ~= B; evs : otway |] \ |
245 \ ==> Crypt (shrK A) {|NA, Agent A, Agent B|} : parts (spies evs) --> \ |
256 \ ==> Crypt (shrK A) {|NA, Agent A, Agent B|} : parts (spies evs) --> \ |
246 \ Says A B {|NA, Agent A, Agent B, \ |
257 \ Says A B {|NA, Agent A, Agent B, \ |
247 \ Crypt (shrK A) {|NA, Agent A, Agent B|}|} : set evs"; |
258 \ Crypt (shrK A) {|NA, Agent A, Agent B|}|} : set evs"; |
|
259 by (parts_induct_tac 1); |
248 by (parts_induct_tac 1); |
260 by (ALLGOALS Blast_tac); |
249 by (ALLGOALS Blast_tac); |
261 qed_spec_mp "Crypt_imp_OR1"; |
250 qed_spec_mp "Crypt_imp_OR1"; |
262 |
251 |
263 |
252 |
264 (*Crucial property: If the encrypted message appears, and A has used NA |
253 (*Crucial property: If the encrypted message appears, and A has used NA |
265 to start a run, then it originated with the Server!*) |
254 to start a run, then it originated with the Server!*) |
266 (*Only it is FALSE. Somebody could make a fake message to Server |
255 (*Only it is FALSE. Somebody could make a fake message to Server |
267 substituting some other nonce NA' for NB.*) |
256 substituting some other nonce NA' for NB.*) |
268 Goal |
257 Goal "[| A ~: bad; evs : otway |] \ |
269 "!!evs. [| A ~: bad; evs : otway |] \ |
258 \ ==> Crypt (shrK A) {|NA, Key K|} : parts (spies evs) --> \ |
270 \ ==> Crypt (shrK A) {|NA, Key K|} : parts (spies evs) --> \ |
259 \ Says A B {|NA, Agent A, Agent B, \ |
271 \ Says A B {|NA, Agent A, Agent B, \ |
260 \ Crypt (shrK A) {|NA, Agent A, Agent B|}|} \ |
272 \ Crypt (shrK A) {|NA, Agent A, Agent B|}|} \ |
261 \ : set evs --> \ |
273 \ : set evs --> \ |
262 \ (EX B NB. Says Server B \ |
274 \ (EX B NB. Says Server B \ |
263 \ {|NA, \ |
275 \ {|NA, \ |
264 \ Crypt (shrK A) {|NA, Key K|}, \ |
276 \ Crypt (shrK A) {|NA, Key K|}, \ |
265 \ Crypt (shrK B) {|NB, Key K|}|} : set evs)"; |
277 \ Crypt (shrK B) {|NB, Key K|}|} : set evs)"; |
|
278 by (parts_induct_tac 1); |
266 by (parts_induct_tac 1); |
279 (*Fake*) |
267 (*Fake*) |
280 by (Blast_tac 1); |
268 by (Blast_tac 1); |
281 (*OR1: it cannot be a new Nonce, contradiction.*) |
269 (*OR1: it cannot be a new Nonce, contradiction.*) |
282 by (Blast_tac 1); |
270 by (Blast_tac 1); |