47 AddSEs [not_Says_to_self RSN (2, rev_notE)]; |
51 AddSEs [not_Says_to_self RSN (2, rev_notE)]; |
48 |
52 |
49 (*For reasoning about the encrypted portion of message NS3*) |
53 (*For reasoning about the encrypted portion of message NS3*) |
50 goal thy "!!evs. Says S A (Crypt KA {|N, B, K, X|}) : set evs \ |
54 goal thy "!!evs. Says S A (Crypt KA {|N, B, K, X|}) : set evs \ |
51 \ ==> X : parts (spies evs)"; |
55 \ ==> X : parts (spies evs)"; |
52 by (blast_tac (claset() addSEs spies_partsEs) 1); |
56 by (Blast_tac 1); |
53 qed "NS3_msg_in_parts_spies"; |
57 qed "NS3_msg_in_parts_spies"; |
54 |
58 |
55 goal thy |
59 goal thy |
56 "!!evs. Says Server A (Crypt (shrK A) {|NA, B, K, X|}) : set evs \ |
60 "!!evs. Says Server A (Crypt (shrK A) {|NA, B, K, X|}) : set evs \ |
57 \ ==> K : parts (spies evs)"; |
61 \ ==> K : parts (spies evs)"; |
58 by (blast_tac (claset() addSEs spies_partsEs) 1); |
62 by (Blast_tac 1); |
59 qed "Oops_parts_spies"; |
63 qed "Oops_parts_spies"; |
60 |
64 |
61 (*For proving the easier theorems about X ~: parts (spies evs).*) |
65 (*For proving the easier theorems about X ~: parts (spies evs).*) |
62 fun parts_induct_tac i = |
66 fun parts_induct_tac i = |
63 EVERY [etac ns_shared.induct i, |
67 EVERY [etac ns_shared.induct i, |
72 |
76 |
73 (*Spy never sees another agent's shared key! (unless it's bad at start)*) |
77 (*Spy never sees another agent's shared key! (unless it's bad at start)*) |
74 goal thy |
78 goal thy |
75 "!!evs. evs : ns_shared ==> (Key (shrK A) : parts (spies evs)) = (A : bad)"; |
79 "!!evs. evs : ns_shared ==> (Key (shrK A) : parts (spies evs)) = (A : bad)"; |
76 by (parts_induct_tac 1); |
80 by (parts_induct_tac 1); |
77 by (Fake_parts_insert_tac 1); |
|
78 by (ALLGOALS Blast_tac); |
81 by (ALLGOALS Blast_tac); |
79 qed "Spy_see_shrK"; |
82 qed "Spy_see_shrK"; |
80 Addsimps [Spy_see_shrK]; |
83 Addsimps [Spy_see_shrK]; |
81 |
84 |
82 goal thy |
85 goal thy |
83 "!!evs. evs : ns_shared ==> (Key (shrK A) : analz (spies evs)) = (A : bad)"; |
86 "!!evs. evs : ns_shared ==> (Key (shrK A) : analz (spies evs)) = (A : bad)"; |
84 by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset())); |
87 by (Auto_tac()); |
85 qed "Spy_analz_shrK"; |
88 qed "Spy_analz_shrK"; |
86 Addsimps [Spy_analz_shrK]; |
89 Addsimps [Spy_analz_shrK]; |
87 |
90 |
88 goal thy "!!A. [| Key (shrK A) : parts (spies evs); \ |
91 AddSDs [Spy_see_shrK RSN (2, rev_iffD1), |
89 \ evs : ns_shared |] ==> A:bad"; |
92 Spy_analz_shrK RSN (2, rev_iffD1)]; |
90 by (blast_tac (claset() addDs [Spy_see_shrK]) 1); |
|
91 qed "Spy_see_shrK_D"; |
|
92 |
|
93 bind_thm ("Spy_analz_shrK_D", analz_subset_parts RS subsetD RS Spy_see_shrK_D); |
|
94 AddSDs [Spy_see_shrK_D, Spy_analz_shrK_D]; |
|
95 |
93 |
96 |
94 |
97 (*Nobody can have used non-existent keys!*) |
95 (*Nobody can have used non-existent keys!*) |
98 goal thy "!!evs. evs : ns_shared ==> \ |
96 goal thy "!!evs. evs : ns_shared ==> \ |
99 \ Key K ~: used evs --> K ~: keysFor (parts (spies evs))"; |
97 \ Key K ~: used evs --> K ~: keysFor (parts (spies evs))"; |
103 (claset() addSDs [impOfSubs (parts_insert_subset_Un RS keysFor_mono)] |
101 (claset() addSDs [impOfSubs (parts_insert_subset_Un RS keysFor_mono)] |
104 addIs [impOfSubs analz_subset_parts] |
102 addIs [impOfSubs analz_subset_parts] |
105 addDs [impOfSubs (analz_subset_parts RS keysFor_mono)] |
103 addDs [impOfSubs (analz_subset_parts RS keysFor_mono)] |
106 addss (simpset())) 1); |
104 addss (simpset())) 1); |
107 (*NS2, NS4, NS5*) |
105 (*NS2, NS4, NS5*) |
108 by (ALLGOALS (blast_tac (claset() addSEs spies_partsEs))); |
106 by (ALLGOALS (Blast_tac)); |
109 qed_spec_mp "new_keys_not_used"; |
107 qed_spec_mp "new_keys_not_used"; |
110 |
108 |
111 bind_thm ("new_keys_not_analzd", |
109 bind_thm ("new_keys_not_analzd", |
112 [analz_subset_parts RS keysFor_mono, |
110 [analz_subset_parts RS keysFor_mono, |
113 new_keys_not_used] MRS contra_subsetD); |
111 new_keys_not_used] MRS contra_subsetD); |
136 \ A ~: bad; evs : ns_shared |] \ |
134 \ A ~: bad; evs : ns_shared |] \ |
137 \ ==> Says Server A (Crypt (shrK A) {|NA, Agent B, Key K, X|}) \ |
135 \ ==> Says Server A (Crypt (shrK A) {|NA, Agent B, Key K, X|}) \ |
138 \ : set evs"; |
136 \ : set evs"; |
139 by (etac rev_mp 1); |
137 by (etac rev_mp 1); |
140 by (parts_induct_tac 1); |
138 by (parts_induct_tac 1); |
141 by (Fake_parts_insert_tac 1); |
139 by (Blast_tac 1); |
142 qed "A_trusts_NS2"; |
140 qed "A_trusts_NS2"; |
143 |
141 |
144 |
142 |
145 goal thy |
143 goal thy |
146 "!!evs. [| Crypt (shrK A) {|NA, Agent B, Key K, X|} : parts (spies evs); \ |
144 "!!evs. [| Crypt (shrK A) {|NA, Agent B, Key K, X|} : parts (spies evs); \ |
160 \ ==> (K ~: range shrK & X = (Crypt (shrK B) {|Key K, Agent A|})) \ |
158 \ ==> (K ~: range shrK & X = (Crypt (shrK B) {|Key K, Agent A|})) \ |
161 \ | X : analz (spies evs)"; |
159 \ | X : analz (spies evs)"; |
162 by (case_tac "A : bad" 1); |
160 by (case_tac "A : bad" 1); |
163 by (fast_tac (claset() addSDs [Says_imp_spies RS analz.Inj] |
161 by (fast_tac (claset() addSDs [Says_imp_spies RS analz.Inj] |
164 addss (simpset())) 1); |
162 addss (simpset())) 1); |
165 by (blast_tac (claset() addSDs [Says_imp_spies RS parts.Inj, cert_A_form]) 1); |
163 by (blast_tac (claset() addSDs [cert_A_form]) 1); |
166 qed "Says_S_message_form"; |
164 qed "Says_S_message_form"; |
167 |
165 |
168 |
166 |
169 (*For proofs involving analz.*) |
167 (*For proofs involving analz.*) |
170 val analz_spies_tac = |
168 val analz_spies_tac = |
189 goal thy |
187 goal thy |
190 "!!evs. [| evs : ns_shared; Kab ~: range shrK |] ==> \ |
188 "!!evs. [| evs : ns_shared; Kab ~: range shrK |] ==> \ |
191 \ (Crypt KAB X) : parts (spies evs) & \ |
189 \ (Crypt KAB X) : parts (spies evs) & \ |
192 \ Key K : parts {X} --> Key K : parts (spies evs)"; |
190 \ Key K : parts {X} --> Key K : parts (spies evs)"; |
193 by (parts_induct_tac 1); |
191 by (parts_induct_tac 1); |
194 (*Deals with Faked messages*) |
192 (*Fake*) |
195 by (blast_tac (claset() addSEs partsEs |
193 by (blast_tac (claset() addSEs partsEs |
196 addDs [impOfSubs parts_insert_subset_Un]) 1); |
194 addDs [impOfSubs parts_insert_subset_Un]) 1); |
197 (*Base, NS4 and NS5*) |
195 (*Base, NS4 and NS5*) |
198 by (Auto_tac()); |
196 by (Auto_tac()); |
199 result(); |
197 result(); |
240 by (ex_strip_tac 2); |
238 by (ex_strip_tac 2); |
241 by (Blast_tac 2); |
239 by (Blast_tac 2); |
242 (*NS2: it can't be a new key*) |
240 (*NS2: it can't be a new key*) |
243 by (expand_case_tac "K = ?y" 1); |
241 by (expand_case_tac "K = ?y" 1); |
244 by (REPEAT (ares_tac [refl,exI,impI,conjI] 2)); |
242 by (REPEAT (ares_tac [refl,exI,impI,conjI] 2)); |
245 by (blast_tac (claset() delrules [conjI] (*prevent splitup into 4 subgoals*) |
243 by (Blast_tac 1); |
246 addSEs spies_partsEs) 1); |
|
247 val lemma = result(); |
244 val lemma = result(); |
248 |
245 |
249 (*In messages of this form, the session key uniquely identifies the rest*) |
246 (*In messages of this form, the session key uniquely identifies the rest*) |
250 goal thy |
247 goal thy |
251 "!!evs. [| Says Server A \ |
248 "!!evs. [| Says Server A \ |
276 (*Oops*) |
273 (*Oops*) |
277 by (blast_tac (claset() addDs [unique_session_keys]) 5); |
274 by (blast_tac (claset() addDs [unique_session_keys]) 5); |
278 (*NS3, replay sub-case*) |
275 (*NS3, replay sub-case*) |
279 by (Blast_tac 4); |
276 by (Blast_tac 4); |
280 (*NS2*) |
277 (*NS2*) |
281 by (blast_tac (claset() addSEs spies_partsEs |
278 by (Blast_tac 2); |
282 addIs [parts_insertI, |
|
283 impOfSubs analz_subset_parts]) 2); |
|
284 (*Fake*) |
279 (*Fake*) |
285 by (spy_analz_tac 1); |
280 by (spy_analz_tac 1); |
286 (*NS3, Server sub-case*) (**LEVEL 6 **) |
281 (*NS3, Server sub-case*) (**LEVEL 6 **) |
287 by (clarify_tac (claset() delrules [impCE]) 1); |
282 by (clarify_tac (claset() delrules [impCE]) 1); |
288 by (forward_tac [Says_imp_spies RS parts.Inj RS A_trusts_NS2] 1); |
283 by (forward_tac [Says_imp_spies RS parts.Inj RS A_trusts_NS2] 1); |
289 by (assume_tac 2); |
284 by (assume_tac 2); |
290 by (blast_tac (claset() addDs [Says_imp_spies RS analz.Inj RS |
285 by (blast_tac (claset() addDs [Says_imp_spies RS analz.Inj RS |
291 Crypt_Spy_analz_bad]) 1); |
286 Crypt_Spy_analz_bad]) 1); |
292 by (blast_tac (claset() addDs [unique_session_keys]) 1); |
287 by (blast_tac (claset() addDs [unique_session_keys]) 1); |
293 val lemma = result() RS mp RS mp RSN(2,rev_notE); |
288 val lemma = result() RS mp RS mp RSN(2,rev_notE); |
294 |
289 |
295 |
290 |
296 (*Final version: Server's message in the most abstract form*) |
291 (*Final version: Server's message in the most abstract form*) |
318 \ (Crypt (shrK A) {|NA, Agent B, Key K, \ |
313 \ (Crypt (shrK A) {|NA, Agent B, Key K, \ |
319 \ Crypt (shrK B) {|Key K, Agent A|}|}) \ |
314 \ Crypt (shrK B) {|Key K, Agent A|}|}) \ |
320 \ : set evs"; |
315 \ : set evs"; |
321 by (etac rev_mp 1); |
316 by (etac rev_mp 1); |
322 by (parts_induct_tac 1); |
317 by (parts_induct_tac 1); |
323 by (Fake_parts_insert_tac 1); |
|
324 (*Fake case*) |
|
325 by (ALLGOALS Blast_tac); |
318 by (ALLGOALS Blast_tac); |
326 qed "B_trusts_NS3"; |
319 qed "B_trusts_NS3"; |
327 |
320 |
328 |
321 |
329 goal thy |
322 goal thy |
337 by (etac rev_mp 1); |
330 by (etac rev_mp 1); |
338 by (etac rev_mp 1); |
331 by (etac rev_mp 1); |
339 by (parts_induct_tac 1); |
332 by (parts_induct_tac 1); |
340 (*NS3*) |
333 (*NS3*) |
341 by (Blast_tac 3); |
334 by (Blast_tac 3); |
342 by (Fake_parts_insert_tac 1); |
335 by (Blast_tac 1); |
343 (*NS2: contradiction from the assumptions |
336 (*NS2: contradiction from the assumptions |
344 Key K ~: used evs2 and Crypt K (Nonce NB) : parts (spies evs2) *) |
337 Key K ~: used evs2 and Crypt K (Nonce NB) : parts (spies evs2) *) |
345 by (blast_tac (claset() addSEs [new_keys_not_used RSN (2,rev_notE)] |
338 by (blast_tac (claset() addSEs [new_keys_not_used RSN (2,rev_notE)] |
346 addSDs [Crypt_imp_keysFor]) 1); |
339 addSDs [Crypt_imp_keysFor]) 1); |
347 (**LEVEL 7**) |
340 (**LEVEL 7**) |
348 (*NS4*) |
341 (*NS4*) |
349 by (Clarify_tac 1); |
342 by (Clarify_tac 1); |
350 by (not_bad_tac "Ba" 1); |
343 by (not_bad_tac "Ba" 1); |
351 by (blast_tac (claset() addDs [Says_imp_spies RS parts.Inj RS B_trusts_NS3, |
344 by (blast_tac (claset() addDs [B_trusts_NS3, unique_session_keys]) 1); |
352 unique_session_keys]) 1); |
|
353 qed "A_trusts_NS4_lemma"; |
345 qed "A_trusts_NS4_lemma"; |
354 |
346 |
355 |
347 |
356 (*This version no longer assumes that K is secure*) |
348 (*This version no longer assumes that K is secure*) |
357 goal thy |
349 goal thy |
379 by (etac rev_mp 1); |
371 by (etac rev_mp 1); |
380 by (etac rev_mp 1); |
372 by (etac rev_mp 1); |
381 by (parts_induct_tac 1); |
373 by (parts_induct_tac 1); |
382 by (ALLGOALS (asm_simp_tac (simpset() addsimps [ex_disj_distrib]))); |
374 by (ALLGOALS (asm_simp_tac (simpset() addsimps [ex_disj_distrib]))); |
383 by (ALLGOALS Clarify_tac); |
375 by (ALLGOALS Clarify_tac); |
384 by (Fake_parts_insert_tac 1); |
376 by (Blast_tac 1); |
385 (**LEVEL 7**) |
377 (**LEVEL 7**) |
386 (*NS2*) |
378 (*NS2*) |
387 by (blast_tac (claset() addSEs [new_keys_not_used RSN (2,rev_notE)] |
379 by (blast_tac (claset() addSEs [new_keys_not_used RSN (2,rev_notE)] |
388 addSDs [Crypt_imp_keysFor]) 1); |
380 addSDs [Crypt_imp_keysFor]) 1); |
389 (*NS4*) |
381 (*NS4*) |
405 \ Says B A (Crypt K (Nonce NB)) : set evs --> \ |
397 \ Says B A (Crypt K (Nonce NB)) : set evs --> \ |
406 \ Crypt K {|Nonce NB, Nonce NB|} : parts (spies evs) --> \ |
398 \ Crypt K {|Nonce NB, Nonce NB|} : parts (spies evs) --> \ |
407 \ Says A B (Crypt K {|Nonce NB, Nonce NB|}) : set evs"; |
399 \ Says A B (Crypt K {|Nonce NB, Nonce NB|}) : set evs"; |
408 by (parts_induct_tac 1); |
400 by (parts_induct_tac 1); |
409 (*NS4*) |
401 (*NS4*) |
410 by (blast_tac (claset() addSEs spies_partsEs) 4); |
402 by (Blast_tac 4); |
411 (*NS3*) |
403 (*NS3*) |
412 by (blast_tac (claset() addSDs [Says_imp_spies RS parts.Inj, cert_A_form]) 3); |
404 by (blast_tac (claset() addSDs [cert_A_form]) 3); |
413 (*NS2*) |
405 (*NS2*) |
414 by (blast_tac (claset() addSEs [new_keys_not_used RSN (2,rev_notE)] |
406 by (blast_tac (claset() addSEs [new_keys_not_used RSN (2,rev_notE)] |
415 addSDs [Crypt_imp_keysFor]) 2); |
407 addSDs [Crypt_imp_keysFor]) 2); |
416 by (Fake_parts_insert_tac 1); |
408 by (Blast_tac 1); |
417 (**LEVEL 5**) |
409 (**LEVEL 5**) |
418 (*NS5*) |
410 (*NS5*) |
419 by (Clarify_tac 1); |
411 by (Clarify_tac 1); |
420 by (not_bad_tac "Aa" 1); |
412 by (not_bad_tac "Aa" 1); |
421 by (blast_tac (claset() addDs [Says_imp_spies RS parts.Inj RS A_trusts_NS2, |
413 by (blast_tac (claset() addDs [A_trusts_NS2, unique_session_keys]) 1); |
422 unique_session_keys]) 1); |
|
423 val lemma = result(); |
414 val lemma = result(); |
424 |
415 |
425 |
416 |
426 (*Very strong Oops condition reveals protocol's weakness*) |
417 (*Very strong Oops condition reveals protocol's weakness*) |
427 goal thy |
418 goal thy |