219 delrules [conjI] (*no split-up to 4 subgoals*)) 1); |
213 delrules [conjI] (*no split-up to 4 subgoals*)) 1); |
220 val lemma = result(); |
214 val lemma = result(); |
221 |
215 |
222 goal thy |
216 goal thy |
223 "!!evs. [| Says Server A \ |
217 "!!evs. [| Says Server A \ |
224 \ {|Crypt (shrK A) {|Agent B, Key K, NA, NB|}, X|} \ |
218 \ {|Crypt (shrK A) {|Agent B, Key K, na, nb|}, X|} \ |
225 \ : set_of_list evs; \ |
219 \ : set_of_list evs; \ |
226 \ Says Server A' \ |
220 \ Says Server A' \ |
227 \ {|Crypt (shrK A') {|Agent B', Key K, NA', NB'|}, X'|} \ |
221 \ {|Crypt (shrK A') {|Agent B', Key K, na', nb'|}, X'|} \ |
228 \ : set_of_list evs; \ |
222 \ : set_of_list evs; \ |
229 \ evs : yahalom lost |] \ |
223 \ evs : yahalom lost |] \ |
230 \ ==> A=A' & B=B' & NA=NA' & NB=NB'"; |
224 \ ==> A=A' & B=B' & na=na' & nb=nb'"; |
231 by (prove_unique_tac lemma 1); |
225 by (prove_unique_tac lemma 1); |
232 qed "unique_session_keys"; |
226 qed "unique_session_keys"; |
233 |
227 |
234 |
228 |
235 (** Crucial secrecy property: Spy does not see the keys sent in msg YM3 **) |
229 (** Crucial secrecy property: Spy does not see the keys sent in msg YM3 **) |
236 |
230 |
237 goal thy |
231 goal thy |
238 "!!evs. [| A ~: lost; B ~: lost; evs : yahalom lost |] \ |
232 "!!evs. [| A ~: lost; B ~: lost; evs : yahalom lost |] \ |
239 \ ==> Says Server A \ |
233 \ ==> Says Server A \ |
240 \ {|Crypt (shrK A) {|Agent B, Key K, NA, NB|}, \ |
234 \ {|Crypt (shrK A) {|Agent B, Key K, na, nb|}, \ |
241 \ Crypt (shrK B) {|Agent A, Key K|}|} \ |
235 \ Crypt (shrK B) {|Agent A, Key K|}|} \ |
242 \ : set_of_list evs --> \ |
236 \ : set_of_list evs --> \ |
243 \ Says A Spy {|NA, NB, Key K|} ~: set_of_list evs --> \ |
237 \ Says A Spy {|na, nb, Key K|} ~: set_of_list evs --> \ |
244 \ Key K ~: analz (sees lost Spy evs)"; |
238 \ Key K ~: analz (sees lost Spy evs)"; |
245 by (etac yahalom.induct 1); |
239 by (etac yahalom.induct 1); |
246 by analz_sees_tac; |
240 by analz_sees_tac; |
247 by (ALLGOALS |
241 by (ALLGOALS |
248 (asm_simp_tac |
242 (asm_simp_tac |
249 (!simpset addsimps [not_parts_not_analz, analz_insert_freshK] |
243 (!simpset addsimps [analz_insert_eq, not_parts_not_analz, |
|
244 analz_insert_freshK] |
250 setloop split_tac [expand_if]))); |
245 setloop split_tac [expand_if]))); |
|
246 (*Oops*) |
|
247 by (blast_tac (!claset addDs [unique_session_keys]) 3); |
251 (*YM3*) |
248 (*YM3*) |
252 by (blast_tac (!claset delrules [impCE] |
249 by (blast_tac (!claset delrules [impCE] |
253 addSEs sees_Spy_partsEs |
250 addSEs sees_Spy_partsEs |
254 addIs [impOfSubs analz_subset_parts]) 2); |
251 addIs [impOfSubs analz_subset_parts]) 2); |
255 (*OR4, Fake*) |
252 (*Fake*) |
256 by (REPEAT_FIRST spy_analz_tac); |
253 by (spy_analz_tac 1); |
257 (*Oops*) |
|
258 by (blast_tac (!claset addDs [unique_session_keys]) 1); |
|
259 val lemma = result() RS mp RS mp RSN(2,rev_notE); |
254 val lemma = result() RS mp RS mp RSN(2,rev_notE); |
260 |
255 |
261 |
256 |
262 (*Final version*) |
257 (*Final version*) |
263 goal thy |
258 goal thy |
264 "!!evs. [| Says Server A \ |
259 "!!evs. [| Says Server A \ |
265 \ {|Crypt (shrK A) {|Agent B, Key K, NA, NB|}, \ |
260 \ {|Crypt (shrK A) {|Agent B, Key K, na, nb|}, \ |
266 \ Crypt (shrK B) {|Agent A, Key K|}|} \ |
261 \ Crypt (shrK B) {|Agent A, Key K|}|} \ |
267 \ : set_of_list evs; \ |
262 \ : set_of_list evs; \ |
268 \ Says A Spy {|NA, NB, Key K|} ~: set_of_list evs; \ |
263 \ Says A Spy {|na, nb, Key K|} ~: set_of_list evs; \ |
269 \ A ~: lost; B ~: lost; evs : yahalom lost |] \ |
264 \ A ~: lost; B ~: lost; evs : yahalom lost |] \ |
270 \ ==> Key K ~: analz (sees lost Spy evs)"; |
265 \ ==> Key K ~: analz (sees lost Spy evs)"; |
271 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1); |
266 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1); |
272 by (blast_tac (!claset addSEs [lemma]) 1); |
267 by (blast_tac (!claset addSEs [lemma]) 1); |
273 qed "Spy_not_see_encrypted_key"; |
268 qed "Spy_not_see_encrypted_key"; |
275 |
270 |
276 (*And other agents don't see the key either.*) |
271 (*And other agents don't see the key either.*) |
277 goal thy |
272 goal thy |
278 "!!evs. [| C ~: {A,B,Server}; \ |
273 "!!evs. [| C ~: {A,B,Server}; \ |
279 \ Says Server A \ |
274 \ Says Server A \ |
280 \ {|Crypt (shrK A) {|Agent B, Key K, NA, NB|}, \ |
275 \ {|Crypt (shrK A) {|Agent B, Key K, na, nb|}, \ |
281 \ Crypt (shrK B) {|Agent A, Key K|}|} \ |
276 \ Crypt (shrK B) {|Agent A, Key K|}|} \ |
282 \ : set_of_list evs; \ |
277 \ : set_of_list evs; \ |
283 \ Says A Spy {|NA, NB, Key K|} ~: set_of_list evs; \ |
278 \ Says A Spy {|na, nb, Key K|} ~: set_of_list evs; \ |
284 \ A ~: lost; B ~: lost; evs : yahalom lost |] \ |
279 \ A ~: lost; B ~: lost; evs : yahalom lost |] \ |
285 \ ==> Key K ~: analz (sees lost C evs)"; |
280 \ ==> Key K ~: analz (sees lost C evs)"; |
286 by (rtac (subset_insertI RS sees_mono RS analz_mono RS contra_subsetD) 1); |
281 by (rtac (subset_insertI RS sees_mono RS analz_mono RS contra_subsetD) 1); |
287 by (rtac (sees_lost_agent_subset_sees_Spy RS analz_mono RS contra_subsetD) 1); |
282 by (rtac (sees_lost_agent_subset_sees_Spy RS analz_mono RS contra_subsetD) 1); |
288 by (FIRSTGOAL (rtac Spy_not_see_encrypted_key)); |
283 by (FIRSTGOAL (rtac Spy_not_see_encrypted_key)); |
306 |
301 |
307 (** Security Guarantee for A upon receiving YM3 **) |
302 (** Security Guarantee for A upon receiving YM3 **) |
308 |
303 |
309 (*If the encrypted message appears then it originated with the Server*) |
304 (*If the encrypted message appears then it originated with the Server*) |
310 goal thy |
305 goal thy |
311 "!!evs. [| Crypt (shrK A) {|Agent B, Key K, NA, NB|} \ |
306 "!!evs. [| Crypt (shrK A) {|Agent B, Key K, na, nb|} \ |
312 \ : parts (sees lost Spy evs); \ |
307 \ : parts (sees lost Spy evs); \ |
313 \ A ~: lost; evs : yahalom lost |] \ |
308 \ A ~: lost; evs : yahalom lost |] \ |
314 \ ==> Says Server A \ |
309 \ ==> Says Server A \ |
315 \ {|Crypt (shrK A) {|Agent B, Key K, NA, NB|}, \ |
310 \ {|Crypt (shrK A) {|Agent B, Key K, na, nb|}, \ |
316 \ Crypt (shrK B) {|Agent A, Key K|}|} \ |
311 \ Crypt (shrK B) {|Agent A, Key K|}|} \ |
317 \ : set_of_list evs"; |
312 \ : set_of_list evs"; |
318 by (etac rev_mp 1); |
313 by (etac rev_mp 1); |
319 by parts_induct_tac; |
314 by parts_induct_tac; |
320 by (Fake_parts_insert_tac 1); |
315 by (Fake_parts_insert_tac 1); |
441 (*Base*) |
436 (*Base*) |
442 by (Blast_tac 1); |
437 by (Blast_tac 1); |
443 (*Fake*) |
438 (*Fake*) |
444 by (spy_analz_tac 1); |
439 by (spy_analz_tac 1); |
445 (*YM4*) (** LEVEL 7 **) |
440 (*YM4*) (** LEVEL 7 **) |
446 by (asm_simp_tac (*X contributes nothing to the result of analz*) |
|
447 (analz_image_freshK_ss addsimps |
|
448 ([ball_conj_distrib, analz_image_freshK, |
|
449 analz_insert_eq, impOfSubs (Un_upper2 RS analz_mono)])) 1); |
|
450 by (not_lost_tac "A" 1); |
441 by (not_lost_tac "A" 1); |
451 by (dtac (Says_imp_sees_Spy' RS parts.Inj RS parts.Fst RS A_trusts_YM3) 1 |
442 by (dtac (Says_imp_sees_Spy' RS parts.Inj RS parts.Fst RS A_trusts_YM3) 1 |
452 THEN REPEAT (assume_tac 1)); |
443 THEN REPEAT (assume_tac 1)); |
453 by (blast_tac (!claset addIs [KeyWithNonceI]) 1); |
444 by (blast_tac (!claset addIs [KeyWithNonceI]) 1); |
454 qed_spec_mp "Nonce_secrecy"; |
445 qed_spec_mp "Nonce_secrecy"; |
559 by (ALLGOALS |
550 by (ALLGOALS |
560 (asm_simp_tac |
551 (asm_simp_tac |
561 (!simpset addsimps ([analz_insert_eq, not_parts_not_analz, |
552 (!simpset addsimps ([analz_insert_eq, not_parts_not_analz, |
562 analz_insert_freshK] @ pushes) |
553 analz_insert_freshK] @ pushes) |
563 setloop split_tac [expand_if]))); |
554 setloop split_tac [expand_if]))); |
|
555 (*Prove YM3 by showing that no NB can also be an NA*) |
|
556 by (blast_tac (!claset addDs [Says_imp_sees_Spy' RS parts.Inj] |
|
557 addSEs [MPair_parts] |
|
558 addDs [no_nonce_YM1_YM2, Says_unique_NB']) 4 |
|
559 THEN flexflex_tac); |
|
560 (*YM2: similar freshness reasoning*) |
|
561 by (blast_tac (!claset addSEs partsEs |
|
562 addDs [Says_imp_sees_Spy' RS analz.Inj, |
|
563 impOfSubs analz_subset_parts]) 3); |
564 (*YM1: NB=NA is impossible anyway, but NA is secret because it is fresh!*) |
564 (*YM1: NB=NA is impossible anyway, but NA is secret because it is fresh!*) |
565 by (blast_tac (!claset addSIs [parts_insertI] |
565 by (blast_tac (!claset addSIs [parts_insertI] |
566 addSEs sees_Spy_partsEs) 2); |
566 addSEs sees_Spy_partsEs) 2); |
567 (*YM2: similar freshness reasoning*) |
|
568 by (blast_tac (!claset addSEs partsEs |
|
569 addDs [Says_imp_sees_Spy' RS analz.Inj, |
|
570 impOfSubs analz_subset_parts]) 2); |
|
571 (*Prove YM3 by showing that no NB can also be an NA*) |
|
572 by (blast_tac (!claset addDs [Says_imp_sees_Spy' RS parts.Inj] |
|
573 addSEs [MPair_parts] |
|
574 addDs [no_nonce_YM1_YM2, Says_unique_NB']) 2 |
|
575 THEN flexflex_tac); |
|
576 (*Fake*) |
567 (*Fake*) |
577 by (spy_analz_tac 1); |
568 by (spy_analz_tac 1); |
578 (** LEVEL 7: YM4 and Oops remain **) |
569 (** LEVEL 7: YM4 and Oops remain **) |
579 (*YM4: key K is visible to Spy, contradicting session key secrecy theorem*) |
570 (*YM4: key K is visible to Spy, contradicting session key secrecy theorem*) |
580 by (REPEAT (Safe_step_tac 1)); |
571 by (REPEAT (Safe_step_tac 1)); |