43 (** For reasoning about the encrypted portion of messages **) |
43 (** For reasoning about the encrypted portion of messages **) |
44 |
44 |
45 (*Lets us treat YM4 using a similar argument as for the Fake case.*) |
45 (*Lets us treat YM4 using a similar argument as for the Fake case.*) |
46 goal thy "!!evs. Says S A {|Crypt (shrK A) Y, X|} : set evs ==> \ |
46 goal thy "!!evs. Says S A {|Crypt (shrK A) Y, X|} : set evs ==> \ |
47 \ X : analz (spies evs)"; |
47 \ X : analz (spies evs)"; |
48 by (blast_tac (!claset addSDs [Says_imp_spies RS analz.Inj]) 1); |
48 by (blast_tac (claset() addSDs [Says_imp_spies RS analz.Inj]) 1); |
49 qed "YM4_analz_spies"; |
49 qed "YM4_analz_spies"; |
50 |
50 |
51 bind_thm ("YM4_parts_spies", |
51 bind_thm ("YM4_parts_spies", |
52 YM4_analz_spies RS (impOfSubs analz_subset_parts)); |
52 YM4_analz_spies RS (impOfSubs analz_subset_parts)); |
53 |
53 |
54 (*Relates to both YM4 and Oops*) |
54 (*Relates to both YM4 and Oops*) |
55 goal thy "!!evs. Says S A {|Crypt (shrK A) {|B,K,NA,NB|}, X|} : set evs ==> \ |
55 goal thy "!!evs. Says S A {|Crypt (shrK A) {|B,K,NA,NB|}, X|} : set evs ==> \ |
56 \ K : parts (spies evs)"; |
56 \ K : parts (spies evs)"; |
57 by (blast_tac (!claset addSEs partsEs |
57 by (blast_tac (claset() addSEs partsEs |
58 addSDs [Says_imp_spies RS parts.Inj]) 1); |
58 addSDs [Says_imp_spies RS parts.Inj]) 1); |
59 qed "YM4_Key_parts_spies"; |
59 qed "YM4_Key_parts_spies"; |
60 |
60 |
61 (*For proving the easier theorems about X ~: parts (spies evs).*) |
61 (*For proving the easier theorems about X ~: parts (spies evs).*) |
62 fun parts_spies_tac i = |
62 fun parts_spies_tac i = |
86 qed "Spy_see_shrK"; |
86 qed "Spy_see_shrK"; |
87 Addsimps [Spy_see_shrK]; |
87 Addsimps [Spy_see_shrK]; |
88 |
88 |
89 goal thy |
89 goal thy |
90 "!!evs. evs : yahalom ==> (Key (shrK A) : analz (spies evs)) = (A : bad)"; |
90 "!!evs. evs : yahalom ==> (Key (shrK A) : analz (spies evs)) = (A : bad)"; |
91 by (auto_tac(!claset addDs [impOfSubs analz_subset_parts], !simpset)); |
91 by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset())); |
92 qed "Spy_analz_shrK"; |
92 qed "Spy_analz_shrK"; |
93 Addsimps [Spy_analz_shrK]; |
93 Addsimps [Spy_analz_shrK]; |
94 |
94 |
95 goal thy "!!A. [| Key (shrK A) : parts (spies evs); \ |
95 goal thy "!!A. [| Key (shrK A) : parts (spies evs); \ |
96 \ evs : yahalom |] ==> A:bad"; |
96 \ evs : yahalom |] ==> A:bad"; |
97 by (blast_tac (!claset addDs [Spy_see_shrK]) 1); |
97 by (blast_tac (claset() addDs [Spy_see_shrK]) 1); |
98 qed "Spy_see_shrK_D"; |
98 qed "Spy_see_shrK_D"; |
99 |
99 |
100 bind_thm ("Spy_analz_shrK_D", analz_subset_parts RS subsetD RS Spy_see_shrK_D); |
100 bind_thm ("Spy_analz_shrK_D", analz_subset_parts RS subsetD RS Spy_see_shrK_D); |
101 AddSDs [Spy_see_shrK_D, Spy_analz_shrK_D]; |
101 AddSDs [Spy_see_shrK_D, Spy_analz_shrK_D]; |
102 |
102 |
105 goal thy "!!evs. evs : yahalom ==> \ |
105 goal thy "!!evs. evs : yahalom ==> \ |
106 \ Key K ~: used evs --> K ~: keysFor (parts (spies evs))"; |
106 \ Key K ~: used evs --> K ~: keysFor (parts (spies evs))"; |
107 by (parts_induct_tac 1); |
107 by (parts_induct_tac 1); |
108 (*Fake*) |
108 (*Fake*) |
109 by (best_tac |
109 by (best_tac |
110 (!claset addSDs [impOfSubs (parts_insert_subset_Un RS keysFor_mono)] |
110 (claset() addSDs [impOfSubs (parts_insert_subset_Un RS keysFor_mono)] |
111 addIs [impOfSubs analz_subset_parts] |
111 addIs [impOfSubs analz_subset_parts] |
112 addDs [impOfSubs (analz_subset_parts RS keysFor_mono)] |
112 addDs [impOfSubs (analz_subset_parts RS keysFor_mono)] |
113 addss (!simpset)) 1); |
113 addss (simpset())) 1); |
114 (*YM2-4: Because Key K is not fresh, etc.*) |
114 (*YM2-4: Because Key K is not fresh, etc.*) |
115 by (REPEAT (blast_tac (!claset addSEs spies_partsEs) 1)); |
115 by (REPEAT (blast_tac (claset() addSEs spies_partsEs) 1)); |
116 qed_spec_mp "new_keys_not_used"; |
116 qed_spec_mp "new_keys_not_used"; |
117 |
117 |
118 bind_thm ("new_keys_not_analzd", |
118 bind_thm ("new_keys_not_analzd", |
119 [analz_subset_parts RS keysFor_mono, |
119 [analz_subset_parts RS keysFor_mono, |
120 new_keys_not_used] MRS contra_subsetD); |
120 new_keys_not_used] MRS contra_subsetD); |
185 \ EX A' B' na' nb' X'. ALL A B na nb X. \ |
185 \ EX A' B' na' nb' X'. ALL A B na nb X. \ |
186 \ Says Server A \ |
186 \ Says Server A \ |
187 \ {|Crypt (shrK A) {|Agent B, Key K, na, nb|}, X|} \ |
187 \ {|Crypt (shrK A) {|Agent B, Key K, na, nb|}, X|} \ |
188 \ : set evs --> A=A' & B=B' & na=na' & nb=nb' & X=X'"; |
188 \ : set evs --> A=A' & B=B' & na=na' & nb=nb' & X=X'"; |
189 by (etac yahalom.induct 1); |
189 by (etac yahalom.induct 1); |
190 by (ALLGOALS (asm_simp_tac (!simpset addsimps [all_conj_distrib]))); |
190 by (ALLGOALS (asm_simp_tac (simpset() addsimps [all_conj_distrib]))); |
191 by (ALLGOALS Clarify_tac); |
191 by (ALLGOALS Clarify_tac); |
192 by (ex_strip_tac 2); |
192 by (ex_strip_tac 2); |
193 by (Blast_tac 2); |
193 by (Blast_tac 2); |
194 (*Remaining case: YM3*) |
194 (*Remaining case: YM3*) |
195 by (expand_case_tac "K = ?y" 1); |
195 by (expand_case_tac "K = ?y" 1); |
196 by (REPEAT (ares_tac [refl,exI,impI,conjI] 2)); |
196 by (REPEAT (ares_tac [refl,exI,impI,conjI] 2)); |
197 (*...we assume X is a recent message and handle this case by contradiction*) |
197 (*...we assume X is a recent message and handle this case by contradiction*) |
198 by (blast_tac (!claset addSEs spies_partsEs |
198 by (blast_tac (claset() addSEs spies_partsEs |
199 delrules [conjI] (*no split-up to 4 subgoals*)) 1); |
199 delrules [conjI] (*no split-up to 4 subgoals*)) 1); |
200 val lemma = result(); |
200 val lemma = result(); |
201 |
201 |
202 goal thy |
202 goal thy |
203 "!!evs. [| Says Server A \ |
203 "!!evs. [| Says Server A \ |
222 \ Key K ~: analz (spies evs)"; |
222 \ Key K ~: analz (spies evs)"; |
223 by (etac yahalom.induct 1); |
223 by (etac yahalom.induct 1); |
224 by analz_spies_tac; |
224 by analz_spies_tac; |
225 by (ALLGOALS |
225 by (ALLGOALS |
226 (asm_simp_tac |
226 (asm_simp_tac |
227 (!simpset addsimps (expand_ifs@pushes) |
227 (simpset() addsimps (expand_ifs@pushes) |
228 addsimps [analz_insert_eq, analz_insert_freshK]))); |
228 addsimps [analz_insert_eq, analz_insert_freshK]))); |
229 (*Oops*) |
229 (*Oops*) |
230 by (blast_tac (!claset addDs [unique_session_keys]) 3); |
230 by (blast_tac (claset() addDs [unique_session_keys]) 3); |
231 (*YM3*) |
231 (*YM3*) |
232 by (blast_tac (!claset delrules [impCE] |
232 by (blast_tac (claset() delrules [impCE] |
233 addSEs spies_partsEs |
233 addSEs spies_partsEs |
234 addIs [impOfSubs analz_subset_parts]) 2); |
234 addIs [impOfSubs analz_subset_parts]) 2); |
235 (*Fake*) |
235 (*Fake*) |
236 by (spy_analz_tac 1); |
236 by (spy_analz_tac 1); |
237 val lemma = result() RS mp RS mp RSN(2,rev_notE); |
237 val lemma = result() RS mp RS mp RSN(2,rev_notE); |
245 \ : set evs; \ |
245 \ : set evs; \ |
246 \ Says A Spy {|na, nb, Key K|} ~: set evs; \ |
246 \ Says A Spy {|na, nb, Key K|} ~: set evs; \ |
247 \ A ~: bad; B ~: bad; evs : yahalom |] \ |
247 \ A ~: bad; B ~: bad; evs : yahalom |] \ |
248 \ ==> Key K ~: analz (spies evs)"; |
248 \ ==> Key K ~: analz (spies evs)"; |
249 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1); |
249 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1); |
250 by (blast_tac (!claset addSEs [lemma]) 1); |
250 by (blast_tac (claset() addSEs [lemma]) 1); |
251 qed "Spy_not_see_encrypted_key"; |
251 qed "Spy_not_see_encrypted_key"; |
252 |
252 |
253 |
253 |
254 (** Security Guarantee for A upon receiving YM3 **) |
254 (** Security Guarantee for A upon receiving YM3 **) |
255 |
255 |
305 by (Fake_parts_insert_tac 1); |
305 by (Fake_parts_insert_tac 1); |
306 (*YM4*) |
306 (*YM4*) |
307 (*A is uncompromised because NB is secure*) |
307 (*A is uncompromised because NB is secure*) |
308 by (not_bad_tac "A" 1); |
308 by (not_bad_tac "A" 1); |
309 (*A's certificate guarantees the existence of the Server message*) |
309 (*A's certificate guarantees the existence of the Server message*) |
310 by (blast_tac (!claset addDs [Says_imp_spies RS parts.Inj RS parts.Fst RS |
310 by (blast_tac (claset() addDs [Says_imp_spies RS parts.Inj RS parts.Fst RS |
311 A_trusts_YM3]) 1); |
311 A_trusts_YM3]) 1); |
312 bind_thm ("B_trusts_YM4_newK", result() RS mp RSN (2, rev_mp)); |
312 bind_thm ("B_trusts_YM4_newK", result() RS mp RSN (2, rev_mp)); |
313 |
313 |
314 |
314 |
315 (**** Towards proving secrecy of Nonce NB ****) |
315 (**** Towards proving secrecy of Nonce NB ****) |
335 |
335 |
336 (*A fresh key cannot be associated with any nonce |
336 (*A fresh key cannot be associated with any nonce |
337 (with respect to a given trace). *) |
337 (with respect to a given trace). *) |
338 goalw thy [KeyWithNonce_def] |
338 goalw thy [KeyWithNonce_def] |
339 "!!evs. Key K ~: used evs ==> ~ KeyWithNonce K NB evs"; |
339 "!!evs. Key K ~: used evs ==> ~ KeyWithNonce K NB evs"; |
340 by (blast_tac (!claset addSEs spies_partsEs) 1); |
340 by (blast_tac (claset() addSEs spies_partsEs) 1); |
341 qed "fresh_not_KeyWithNonce"; |
341 qed "fresh_not_KeyWithNonce"; |
342 |
342 |
343 (*The Server message associates K with NB' and therefore not with any |
343 (*The Server message associates K with NB' and therefore not with any |
344 other nonce NB.*) |
344 other nonce NB.*) |
345 goalw thy [KeyWithNonce_def] |
345 goalw thy [KeyWithNonce_def] |
346 "!!evs. [| Says Server A \ |
346 "!!evs. [| Says Server A \ |
347 \ {|Crypt (shrK A) {|Agent B, Key K, na, Nonce NB'|}, X|} \ |
347 \ {|Crypt (shrK A) {|Agent B, Key K, na, Nonce NB'|}, X|} \ |
348 \ : set evs; \ |
348 \ : set evs; \ |
349 \ NB ~= NB'; evs : yahalom |] \ |
349 \ NB ~= NB'; evs : yahalom |] \ |
350 \ ==> ~ KeyWithNonce K NB evs"; |
350 \ ==> ~ KeyWithNonce K NB evs"; |
351 by (blast_tac (!claset addDs [unique_session_keys]) 1); |
351 by (blast_tac (claset() addDs [unique_session_keys]) 1); |
352 qed "Says_Server_KeyWithNonce"; |
352 qed "Says_Server_KeyWithNonce"; |
353 |
353 |
354 |
354 |
355 (*The only nonces that can be found with the help of session keys are |
355 (*The only nonces that can be found with the help of session keys are |
356 those distributed as nonce NB by the Server. The form of the theorem |
356 those distributed as nonce NB by the Server. The form of the theorem |
360 (*As with analz_image_freshK, we take some pains to express the property |
360 (*As with analz_image_freshK, we take some pains to express the property |
361 as a logical equivalence so that the simplifier can apply it.*) |
361 as a logical equivalence so that the simplifier can apply it.*) |
362 goal thy |
362 goal thy |
363 "!!evs. P --> (X : analz (G Un H)) --> (X : analz H) ==> \ |
363 "!!evs. P --> (X : analz (G Un H)) --> (X : analz H) ==> \ |
364 \ P --> (X : analz (G Un H)) = (X : analz H)"; |
364 \ P --> (X : analz (G Un H)) = (X : analz H)"; |
365 by (blast_tac (!claset addIs [impOfSubs analz_mono]) 1); |
365 by (blast_tac (claset() addIs [impOfSubs analz_mono]) 1); |
366 val Nonce_secrecy_lemma = result(); |
366 val Nonce_secrecy_lemma = result(); |
367 |
367 |
368 goal thy |
368 goal thy |
369 "!!evs. evs : yahalom ==> \ |
369 "!!evs. evs : yahalom ==> \ |
370 \ (ALL KK. KK <= Compl (range shrK) --> \ |
370 \ (ALL KK. KK <= Compl (range shrK) --> \ |
392 by (spy_analz_tac 1); |
392 by (spy_analz_tac 1); |
393 (*YM4*) (** LEVEL 7 **) |
393 (*YM4*) (** LEVEL 7 **) |
394 by (not_bad_tac "A" 1); |
394 by (not_bad_tac "A" 1); |
395 by (dtac (Says_imp_spies RS parts.Inj RS parts.Fst RS A_trusts_YM3) 1 |
395 by (dtac (Says_imp_spies RS parts.Inj RS parts.Fst RS A_trusts_YM3) 1 |
396 THEN REPEAT (assume_tac 1)); |
396 THEN REPEAT (assume_tac 1)); |
397 by (blast_tac (!claset addIs [KeyWithNonceI]) 1); |
397 by (blast_tac (claset() addIs [KeyWithNonceI]) 1); |
398 qed_spec_mp "Nonce_secrecy"; |
398 qed_spec_mp "Nonce_secrecy"; |
399 |
399 |
400 |
400 |
401 (*Version required below: if NB can be decrypted using a session key then it |
401 (*Version required below: if NB can be decrypted using a session key then it |
402 was distributed with that key. The more general form above is required |
402 was distributed with that key. The more general form above is required |
422 \ --> B ~: bad --> NA = NA' & A = A' & B = B'"; |
422 \ --> B ~: bad --> NA = NA' & A = A' & B = B'"; |
423 by (parts_induct_tac 1); |
423 by (parts_induct_tac 1); |
424 (*Fake*) |
424 (*Fake*) |
425 by (REPEAT (etac (exI RSN (2,exE)) 1) (*stripping EXs makes proof faster*) |
425 by (REPEAT (etac (exI RSN (2,exE)) 1) (*stripping EXs makes proof faster*) |
426 THEN Fake_parts_insert_tac 1); |
426 THEN Fake_parts_insert_tac 1); |
427 by (asm_simp_tac (!simpset addsimps [all_conj_distrib]) 1); |
427 by (asm_simp_tac (simpset() addsimps [all_conj_distrib]) 1); |
428 (*YM2: creation of new Nonce. Move assertion into global context*) |
428 (*YM2: creation of new Nonce. Move assertion into global context*) |
429 by (expand_case_tac "nb = ?y" 1); |
429 by (expand_case_tac "nb = ?y" 1); |
430 by (REPEAT (resolve_tac [exI, conjI, impI, refl] 1)); |
430 by (REPEAT (resolve_tac [exI, conjI, impI, refl] 1)); |
431 by (blast_tac (!claset addSEs spies_partsEs) 1); |
431 by (blast_tac (claset() addSEs spies_partsEs) 1); |
432 val lemma = result(); |
432 val lemma = result(); |
433 |
433 |
434 goal thy |
434 goal thy |
435 "!!evs.[| Crypt (shrK B) {|Agent A, Nonce NA, nb|} : parts (spies evs); \ |
435 "!!evs.[| Crypt (shrK B) {|Agent A, Nonce NA, nb|} : parts (spies evs); \ |
436 \ Crypt (shrK B') {|Agent A', Nonce NA', nb|} : parts (spies evs); \ |
436 \ Crypt (shrK B') {|Agent A', Nonce NA', nb|} : parts (spies evs); \ |
448 \ Says C' D' {|X', Crypt (shrK B') {|Agent A', Nonce NA', nb|}|} \ |
448 \ Says C' D' {|X', Crypt (shrK B') {|Agent A', Nonce NA', nb|}|} \ |
449 \ : set evs; \ |
449 \ : set evs; \ |
450 \ nb ~: analz (spies evs); evs : yahalom |] \ |
450 \ nb ~: analz (spies evs); evs : yahalom |] \ |
451 \ ==> NA' = NA & A' = A & B' = B"; |
451 \ ==> NA' = NA & A' = A & B' = B"; |
452 by (not_bad_tac "B'" 1); |
452 by (not_bad_tac "B'" 1); |
453 by (blast_tac (!claset addSDs [Says_imp_spies RS parts.Inj] |
453 by (blast_tac (claset() addSDs [Says_imp_spies RS parts.Inj] |
454 addSEs [MPair_parts] |
454 addSEs [MPair_parts] |
455 addDs [unique_NB]) 1); |
455 addDs [unique_NB]) 1); |
456 qed "Says_unique_NB"; |
456 qed "Says_unique_NB"; |
457 |
457 |
458 |
458 |
463 \ ==> Nonce NB ~: analz (spies evs) --> \ |
463 \ ==> Nonce NB ~: analz (spies evs) --> \ |
464 \ Crypt (shrK B') {|Agent A', Nonce NB, nb'|} : parts(spies evs) --> \ |
464 \ Crypt (shrK B') {|Agent A', Nonce NB, nb'|} : parts(spies evs) --> \ |
465 \ Crypt (shrK B) {|Agent A, Nonce NA, Nonce NB|} ~: parts(spies evs)"; |
465 \ Crypt (shrK B) {|Agent A, Nonce NA, Nonce NB|} ~: parts(spies evs)"; |
466 by (parts_induct_tac 1); |
466 by (parts_induct_tac 1); |
467 by (Fake_parts_insert_tac 1); |
467 by (Fake_parts_insert_tac 1); |
468 by (blast_tac (!claset addDs [Says_imp_spies RS analz.Inj] |
468 by (blast_tac (claset() addDs [Says_imp_spies RS analz.Inj] |
469 addSIs [parts_insertI] |
469 addSIs [parts_insertI] |
470 addSEs partsEs) 1); |
470 addSEs partsEs) 1); |
471 bind_thm ("no_nonce_YM1_YM2", result() RS mp RSN (2,rev_mp) RSN (2,rev_notE)); |
471 bind_thm ("no_nonce_YM1_YM2", result() RS mp RSN (2,rev_mp) RSN (2,rev_notE)); |
472 |
472 |
473 (*The Server sends YM3 only in response to YM2.*) |
473 (*The Server sends YM3 only in response to YM2.*) |
495 \ Nonce NB ~: analz (spies evs)"; |
495 \ Nonce NB ~: analz (spies evs)"; |
496 by (etac yahalom.induct 1); |
496 by (etac yahalom.induct 1); |
497 by analz_spies_tac; |
497 by analz_spies_tac; |
498 by (ALLGOALS |
498 by (ALLGOALS |
499 (asm_simp_tac |
499 (asm_simp_tac |
500 (!simpset addsimps (expand_ifs@pushes) |
500 (simpset() addsimps (expand_ifs@pushes) |
501 addsimps [analz_insert_eq, analz_insert_freshK]))); |
501 addsimps [analz_insert_eq, analz_insert_freshK]))); |
502 (*Prove YM3 by showing that no NB can also be an NA*) |
502 (*Prove YM3 by showing that no NB can also be an NA*) |
503 by (blast_tac (!claset addDs [Says_imp_spies RS parts.Inj] |
503 by (blast_tac (claset() addDs [Says_imp_spies RS parts.Inj] |
504 addSEs [MPair_parts] |
504 addSEs [MPair_parts] |
505 addDs [no_nonce_YM1_YM2, Says_unique_NB]) 4 |
505 addDs [no_nonce_YM1_YM2, Says_unique_NB]) 4 |
506 THEN flexflex_tac); |
506 THEN flexflex_tac); |
507 (*YM2: similar freshness reasoning*) |
507 (*YM2: similar freshness reasoning*) |
508 by (blast_tac (!claset addSEs partsEs |
508 by (blast_tac (claset() addSEs partsEs |
509 addDs [Says_imp_spies RS analz.Inj, |
509 addDs [Says_imp_spies RS analz.Inj, |
510 impOfSubs analz_subset_parts]) 3); |
510 impOfSubs analz_subset_parts]) 3); |
511 (*YM1: NB=NA is impossible anyway, but NA is secret because it is fresh!*) |
511 (*YM1: NB=NA is impossible anyway, but NA is secret because it is fresh!*) |
512 by (blast_tac (!claset addSIs [parts_insertI] |
512 by (blast_tac (claset() addSIs [parts_insertI] |
513 addSEs spies_partsEs) 2); |
513 addSEs spies_partsEs) 2); |
514 (*Fake*) |
514 (*Fake*) |
515 by (spy_analz_tac 1); |
515 by (spy_analz_tac 1); |
516 (** LEVEL 7: YM4 and Oops remain **) |
516 (** LEVEL 7: YM4 and Oops remain **) |
517 by (ALLGOALS Clarify_tac); |
517 by (ALLGOALS Clarify_tac); |
520 by (dtac (Says_imp_spies RS parts.Inj RS parts.Fst RS A_trusts_YM3) 1); |
520 by (dtac (Says_imp_spies RS parts.Inj RS parts.Fst RS A_trusts_YM3) 1); |
521 by (forward_tac [Says_Server_message_form] 3); |
521 by (forward_tac [Says_Server_message_form] 3); |
522 by (forward_tac [Says_Server_imp_YM2] 4); |
522 by (forward_tac [Says_Server_imp_YM2] 4); |
523 by (REPEAT_FIRST (eresolve_tac [asm_rl, bexE, exE, disjE])); |
523 by (REPEAT_FIRST (eresolve_tac [asm_rl, bexE, exE, disjE])); |
524 (* use Says_unique_NB to identify message components: Aa=A, Ba=B, NAa=NA *) |
524 (* use Says_unique_NB to identify message components: Aa=A, Ba=B, NAa=NA *) |
525 by (blast_tac (!claset addDs [Says_unique_NB, Spy_not_see_encrypted_key, |
525 by (blast_tac (claset() addDs [Says_unique_NB, Spy_not_see_encrypted_key, |
526 impOfSubs Fake_analz_insert]) 1); |
526 impOfSubs Fake_analz_insert]) 1); |
527 (** LEVEL 14 **) |
527 (** LEVEL 14 **) |
528 (*Oops case: if the nonce is betrayed now, show that the Oops event is |
528 (*Oops case: if the nonce is betrayed now, show that the Oops event is |
529 covered by the quantified Oops assumption.*) |
529 covered by the quantified Oops assumption.*) |
530 by (full_simp_tac (!simpset addsimps [all_conj_distrib]) 1); |
530 by (full_simp_tac (simpset() addsimps [all_conj_distrib]) 1); |
531 by (forward_tac [Says_Server_imp_YM2] 1 THEN assume_tac 1 THEN etac exE 1); |
531 by (forward_tac [Says_Server_imp_YM2] 1 THEN assume_tac 1 THEN etac exE 1); |
532 by (expand_case_tac "NB = NBa" 1); |
532 by (expand_case_tac "NB = NBa" 1); |
533 (*If NB=NBa then all other components of the Oops message agree*) |
533 (*If NB=NBa then all other components of the Oops message agree*) |
534 by (blast_tac (!claset addDs [Says_unique_NB]) 1 THEN flexflex_tac); |
534 by (blast_tac (claset() addDs [Says_unique_NB]) 1 THEN flexflex_tac); |
535 (*case NB ~= NBa*) |
535 (*case NB ~= NBa*) |
536 by (asm_simp_tac (!simpset addsimps [single_Nonce_secrecy]) 1); |
536 by (asm_simp_tac (simpset() addsimps [single_Nonce_secrecy]) 1); |
537 by (blast_tac (!claset addSEs [MPair_parts] |
537 by (blast_tac (claset() addSEs [MPair_parts] |
538 addDs [Says_imp_spies RS parts.Inj, |
538 addDs [Says_imp_spies RS parts.Inj, |
539 no_nonce_YM1_YM2 (*to prove NB~=NAa*) ]) 1); |
539 no_nonce_YM1_YM2 (*to prove NB~=NAa*) ]) 1); |
540 bind_thm ("Spy_not_see_NB", result() RSN(2,rev_mp) RSN(2,rev_mp)); |
540 bind_thm ("Spy_not_see_NB", result() RSN(2,rev_mp) RSN(2,rev_mp)); |
541 |
541 |
542 |
542 |
563 dtac B_trusts_YM4_shrK 1); |
563 dtac B_trusts_YM4_shrK 1); |
564 by (dtac B_trusts_YM4_newK 3); |
564 by (dtac B_trusts_YM4_newK 3); |
565 by (REPEAT_FIRST (eresolve_tac [asm_rl, exE])); |
565 by (REPEAT_FIRST (eresolve_tac [asm_rl, exE])); |
566 by (forward_tac [Says_Server_imp_YM2] 1 THEN assume_tac 1); |
566 by (forward_tac [Says_Server_imp_YM2] 1 THEN assume_tac 1); |
567 by (dtac unique_session_keys 1 THEN REPEAT (assume_tac 1)); |
567 by (dtac unique_session_keys 1 THEN REPEAT (assume_tac 1)); |
568 by (blast_tac (!claset addDs [Says_unique_NB]) 1); |
568 by (blast_tac (claset() addDs [Says_unique_NB]) 1); |
569 qed "B_trusts_YM4"; |
569 qed "B_trusts_YM4"; |
570 |
570 |
571 |
571 |
572 |
572 |
573 (*** Authenticating B to A ***) |
573 (*** Authenticating B to A ***) |
594 by (etac yahalom.induct 1); |
594 by (etac yahalom.induct 1); |
595 by (ALLGOALS Asm_simp_tac); |
595 by (ALLGOALS Asm_simp_tac); |
596 (*YM4*) |
596 (*YM4*) |
597 by (Blast_tac 2); |
597 by (Blast_tac 2); |
598 (*YM3*) |
598 (*YM3*) |
599 by (best_tac (!claset addSDs [B_Said_YM2, Says_imp_spies RS parts.Inj] |
599 by (best_tac (claset() addSDs [B_Said_YM2, Says_imp_spies RS parts.Inj] |
600 addSEs [MPair_parts]) 1); |
600 addSEs [MPair_parts]) 1); |
601 val lemma = result() RSN (2, rev_mp) RS mp |> standard; |
601 val lemma = result() RSN (2, rev_mp) RS mp |> standard; |
602 |
602 |
603 (*If A receives YM3 then B has used nonce NA (and therefore is alive)*) |
603 (*If A receives YM3 then B has used nonce NA (and therefore is alive)*) |
604 goal thy |
604 goal thy |
605 "!!evs. [| Says S A {|Crypt (shrK A) {|Agent B, Key K, Nonce NA, nb|}, X|} \ |
605 "!!evs. [| Says S A {|Crypt (shrK A) {|Agent B, Key K, Nonce NA, nb|}, X|} \ |
606 \ : set evs; \ |
606 \ : set evs; \ |
607 \ A ~: bad; B ~: bad; evs : yahalom |] \ |
607 \ A ~: bad; B ~: bad; evs : yahalom |] \ |
608 \ ==> Says B Server {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, nb|}|} \ |
608 \ ==> Says B Server {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, nb|}|} \ |
609 \ : set evs"; |
609 \ : set evs"; |
610 by (blast_tac (!claset addSDs [A_trusts_YM3, lemma] |
610 by (blast_tac (claset() addSDs [A_trusts_YM3, lemma] |
611 addEs spies_partsEs) 1); |
611 addEs spies_partsEs) 1); |
612 qed "YM3_auth_B_to_A"; |
612 qed "YM3_auth_B_to_A"; |
613 |
613 |
614 |
614 |
615 (*** Authenticating A to B using the certificate Crypt K (Nonce NB) ***) |
615 (*** Authenticating A to B using the certificate Crypt K (Nonce NB) ***) |
626 \ (EX X. Says A B {|X, Crypt K (Nonce NB)|} : set evs)"; |
626 \ (EX X. Says A B {|X, Crypt K (Nonce NB)|} : set evs)"; |
627 by (parts_induct_tac 1); |
627 by (parts_induct_tac 1); |
628 (*Fake*) |
628 (*Fake*) |
629 by (Fake_parts_insert_tac 1); |
629 by (Fake_parts_insert_tac 1); |
630 (*YM3: by new_keys_not_used we note that Crypt K (Nonce NB) could not exist*) |
630 (*YM3: by new_keys_not_used we note that Crypt K (Nonce NB) could not exist*) |
631 by (fast_tac (!claset addSDs [Crypt_imp_invKey_keysFor] addss (!simpset)) 1); |
631 by (fast_tac (claset() addSDs [Crypt_imp_invKey_keysFor] addss (simpset())) 1); |
632 (*YM4: was Crypt K (Nonce NB) the very last message? If not, use ind. hyp.*) |
632 (*YM4: was Crypt K (Nonce NB) the very last message? If not, use ind. hyp.*) |
633 by (asm_simp_tac (!simpset addsimps [ex_disj_distrib]) 1); |
633 by (asm_simp_tac (simpset() addsimps [ex_disj_distrib]) 1); |
634 (*yes: apply unicity of session keys*) |
634 (*yes: apply unicity of session keys*) |
635 by (not_bad_tac "Aa" 1); |
635 by (not_bad_tac "Aa" 1); |
636 by (blast_tac (!claset addSEs [MPair_parts] |
636 by (blast_tac (claset() addSEs [MPair_parts] |
637 addSDs [A_trusts_YM3, B_trusts_YM4_shrK] |
637 addSDs [A_trusts_YM3, B_trusts_YM4_shrK] |
638 addDs [Says_imp_spies RS parts.Inj, |
638 addDs [Says_imp_spies RS parts.Inj, |
639 unique_session_keys]) 1); |
639 unique_session_keys]) 1); |
640 val lemma = normalize_thm [RSspec, RSmp] (result()) |> standard; |
640 val lemma = normalize_thm [RSspec, RSmp] (result()) |> standard; |
641 |
641 |
655 by (REPEAT_FIRST (eresolve_tac [asm_rl, spec])); |
655 by (REPEAT_FIRST (eresolve_tac [asm_rl, spec])); |
656 by (etac (Says_imp_spies RS parts.Inj RS MPair_parts) 1); |
656 by (etac (Says_imp_spies RS parts.Inj RS MPair_parts) 1); |
657 by (rtac lemma 1); |
657 by (rtac lemma 1); |
658 by (rtac Spy_not_see_encrypted_key 2); |
658 by (rtac Spy_not_see_encrypted_key 2); |
659 by (REPEAT_FIRST assume_tac); |
659 by (REPEAT_FIRST assume_tac); |
660 by (blast_tac (!claset addSEs [MPair_parts] |
660 by (blast_tac (claset() addSEs [MPair_parts] |
661 addDs [Says_imp_spies RS parts.Inj]) 1); |
661 addDs [Says_imp_spies RS parts.Inj]) 1); |
662 qed_spec_mp "YM4_imp_A_Said_YM3"; |
662 qed_spec_mp "YM4_imp_A_Said_YM3"; |