1(* Title: HOL/Auth/Kerberos_BAN.thy 2 Author: Giampaolo Bella, Cambridge University Computer Laboratory 3 Copyright 1998 University of Cambridge 4*) 5 6section\<open>The Kerberos Protocol, BAN Version\<close> 7 8theory Kerberos_BAN imports Public begin 9 10text\<open>From page 251 of 11 Burrows, Abadi and Needham (1989). A Logic of Authentication. 12 Proc. Royal Soc. 426 13 14 Confidentiality (secrecy) and authentication properties are also 15 given in a termporal version: strong guarantees in a little abstracted 16 - but very realistic - model. 17\<close> 18 19(* Temporal model of accidents: session keys can be leaked 20 ONLY when they have expired *) 21 22consts 23 24 (*Duration of the session key*) 25 sesKlife :: nat 26 27 (*Duration of the authenticator*) 28 authlife :: nat 29 30text\<open>The ticket should remain fresh for two journeys on the network at least\<close> 31specification (sesKlife) 32 sesKlife_LB [iff]: "2 \<le> sesKlife" 33 by blast 34 35text\<open>The authenticator only for one journey\<close> 36specification (authlife) 37 authlife_LB [iff]: "authlife \<noteq> 0" 38 by blast 39 40abbreviation 41 CT :: "event list \<Rightarrow> nat" where 42 "CT == length " 43 44abbreviation 45 expiredK :: "[nat, event list] \<Rightarrow> bool" where 46 "expiredK T evs == sesKlife + T < CT evs" 47 48abbreviation 49 expiredA :: "[nat, event list] \<Rightarrow> bool" where 50 "expiredA T evs == authlife + T < CT evs" 51 52 53definition 54 (* A is the true creator of X if she has sent X and X never appeared on 55 the trace before this event. Recall that traces grow from head. *) 56 Issues :: "[agent, agent, msg, event list] \<Rightarrow> bool" 57 ("_ Issues _ with _ on _") where 58 "A Issues B with X on evs = 59 (\<exists>Y. Says A B Y \<in> set evs \<and> X \<in> parts {Y} \<and> 60 X \<notin> parts (spies (takeWhile (\<lambda>z. z \<noteq> Says A B Y) (rev evs))))" 61 62definition 63 (* Yields the subtrace of a given trace from its beginning to a given event *) 64 before :: "[event, event list] \<Rightarrow> event list" ("before _ on _") 65 where "before ev on evs = takeWhile (\<lambda>z. z \<noteq> ev) (rev evs)" 66 67definition 68 (* States than an event really appears only once on a trace *) 69 Unique :: "[event, event list] \<Rightarrow> bool" ("Unique _ on _") 70 where "Unique ev on evs = (ev \<notin> set (tl (dropWhile (\<lambda>z. z \<noteq> ev) evs)))" 71 72 73inductive_set bankerberos :: "event list set" 74 where 75 76 Nil: "[] \<in> bankerberos" 77 78 | Fake: "\<lbrakk> evsf \<in> bankerberos; X \<in> synth (analz (spies evsf)) \<rbrakk> 79 \<Longrightarrow> Says Spy B X # evsf \<in> bankerberos" 80 81 82 | BK1: "\<lbrakk> evs1 \<in> bankerberos \<rbrakk> 83 \<Longrightarrow> Says A Server \<lbrace>Agent A, Agent B\<rbrace> # evs1 84 \<in> bankerberos" 85 86 87 | BK2: "\<lbrakk> evs2 \<in> bankerberos; Key K \<notin> used evs2; K \<in> symKeys; 88 Says A' Server \<lbrace>Agent A, Agent B\<rbrace> \<in> set evs2 \<rbrakk> 89 \<Longrightarrow> Says Server A 90 (Crypt (shrK A) 91 \<lbrace>Number (CT evs2), Agent B, Key K, 92 (Crypt (shrK B) \<lbrace>Number (CT evs2), Agent A, Key K\<rbrace>)\<rbrace>) 93 # evs2 \<in> bankerberos" 94 95 96 | BK3: "\<lbrakk> evs3 \<in> bankerberos; 97 Says S A (Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, Ticket\<rbrace>) 98 \<in> set evs3; 99 Says A Server \<lbrace>Agent A, Agent B\<rbrace> \<in> set evs3; 100 \<not> expiredK Tk evs3 \<rbrakk> 101 \<Longrightarrow> Says A B \<lbrace>Ticket, Crypt K \<lbrace>Agent A, Number (CT evs3)\<rbrace> \<rbrace> 102 # evs3 \<in> bankerberos" 103 104 105 | BK4: "\<lbrakk> evs4 \<in> bankerberos; 106 Says A' B \<lbrace>(Crypt (shrK B) \<lbrace>Number Tk, Agent A, Key K\<rbrace>), 107 (Crypt K \<lbrace>Agent A, Number Ta\<rbrace>) \<rbrace> \<in> set evs4; 108 \<not> expiredK Tk evs4; \<not> expiredA Ta evs4 \<rbrakk> 109 \<Longrightarrow> Says B A (Crypt K (Number Ta)) # evs4 110 \<in> bankerberos" 111 112 (*Old session keys may become compromised*) 113 | Oops: "\<lbrakk> evso \<in> bankerberos; 114 Says Server A (Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, Ticket\<rbrace>) 115 \<in> set evso; 116 expiredK Tk evso \<rbrakk> 117 \<Longrightarrow> Notes Spy \<lbrace>Number Tk, Key K\<rbrace> # evso \<in> bankerberos" 118 119 120declare Says_imp_knows_Spy [THEN parts.Inj, dest] 121declare parts.Body [dest] 122declare analz_into_parts [dest] 123declare Fake_parts_insert_in_Un [dest] 124 125text\<open>A "possibility property": there are traces that reach the end.\<close> 126lemma "\<lbrakk>Key K \<notin> used []; K \<in> symKeys\<rbrakk> 127 \<Longrightarrow> \<exists>Timestamp. \<exists>evs \<in> bankerberos. 128 Says B A (Crypt K (Number Timestamp)) 129 \<in> set evs" 130apply (cut_tac sesKlife_LB) 131apply (intro exI bexI) 132apply (rule_tac [2] 133 bankerberos.Nil [THEN bankerberos.BK1, THEN bankerberos.BK2, 134 THEN bankerberos.BK3, THEN bankerberos.BK4]) 135apply (possibility, simp_all (no_asm_simp) add: used_Cons) 136done 137 138subsection\<open>Lemmas for reasoning about predicate "Issues"\<close> 139 140lemma spies_Says_rev: "spies (evs @ [Says A B X]) = insert X (spies evs)" 141apply (induct_tac "evs") 142apply (rename_tac [2] a b) 143apply (induct_tac [2] "a", auto) 144done 145 146lemma spies_Gets_rev: "spies (evs @ [Gets A X]) = spies evs" 147apply (induct_tac "evs") 148apply (rename_tac [2] a b) 149apply (induct_tac [2] "a", auto) 150done 151 152lemma spies_Notes_rev: "spies (evs @ [Notes A X]) = 153 (if A\<in>bad then insert X (spies evs) else spies evs)" 154apply (induct_tac "evs") 155apply (rename_tac [2] a b) 156apply (induct_tac [2] "a", auto) 157done 158 159lemma spies_evs_rev: "spies evs = spies (rev evs)" 160apply (induct_tac "evs") 161apply (rename_tac [2] a b) 162apply (induct_tac [2] "a") 163apply (simp_all (no_asm_simp) add: spies_Says_rev spies_Gets_rev spies_Notes_rev) 164done 165 166lemmas parts_spies_evs_revD2 = spies_evs_rev [THEN equalityD2, THEN parts_mono] 167 168lemma spies_takeWhile: "spies (takeWhile P evs) \<subseteq> spies evs" 169apply (induct_tac "evs") 170apply (rename_tac [2] a b) 171apply (induct_tac [2] "a", auto) 172txt\<open>Resembles \<open>used_subset_append\<close> in theory Event.\<close> 173done 174 175lemmas parts_spies_takeWhile_mono = spies_takeWhile [THEN parts_mono] 176 177 178text\<open>Lemmas for reasoning about predicate "before"\<close> 179lemma used_Says_rev: "used (evs @ [Says A B X]) = parts {X} \<union> (used evs)" 180apply (induct_tac "evs") 181apply simp 182apply (rename_tac a b) 183apply (induct_tac "a") 184apply auto 185done 186 187lemma used_Notes_rev: "used (evs @ [Notes A X]) = parts {X} \<union> (used evs)" 188apply (induct_tac "evs") 189apply simp 190apply (rename_tac a b) 191apply (induct_tac "a") 192apply auto 193done 194 195lemma used_Gets_rev: "used (evs @ [Gets B X]) = used evs" 196apply (induct_tac "evs") 197apply simp 198apply (rename_tac a b) 199apply (induct_tac "a") 200apply auto 201done 202 203lemma used_evs_rev: "used evs = used (rev evs)" 204apply (induct_tac "evs") 205apply simp 206apply (rename_tac a b) 207apply (induct_tac "a") 208apply (simp add: used_Says_rev) 209apply (simp add: used_Gets_rev) 210apply (simp add: used_Notes_rev) 211done 212 213lemma used_takeWhile_used [rule_format]: 214 "x \<in> used (takeWhile P X) \<longrightarrow> x \<in> used X" 215apply (induct_tac "X") 216apply simp 217apply (rename_tac a b) 218apply (induct_tac "a") 219apply (simp_all add: used_Nil) 220apply (blast dest!: initState_into_used)+ 221done 222 223lemma set_evs_rev: "set evs = set (rev evs)" 224apply auto 225done 226 227lemma takeWhile_void [rule_format]: 228 "x \<notin> set evs \<longrightarrow> takeWhile (\<lambda>z. z \<noteq> x) evs = evs" 229apply auto 230done 231 232(**** Inductive proofs about bankerberos ****) 233 234text\<open>Forwarding Lemma for reasoning about the encrypted portion of message BK3\<close> 235lemma BK3_msg_in_parts_spies: 236 "Says S A (Crypt KA \<lbrace>Timestamp, B, K, X\<rbrace>) \<in> set evs 237 \<Longrightarrow> X \<in> parts (spies evs)" 238apply blast 239done 240 241lemma Oops_parts_spies: 242 "Says Server A (Crypt (shrK A) \<lbrace>Timestamp, B, K, X\<rbrace>) \<in> set evs 243 \<Longrightarrow> K \<in> parts (spies evs)" 244apply blast 245done 246 247text\<open>Spy never sees another agent's shared key! (unless it's bad at start)\<close> 248lemma Spy_see_shrK [simp]: 249 "evs \<in> bankerberos \<Longrightarrow> (Key (shrK A) \<in> parts (spies evs)) = (A \<in> bad)" 250apply (erule bankerberos.induct) 251apply (frule_tac [7] Oops_parts_spies) 252apply (frule_tac [5] BK3_msg_in_parts_spies, simp_all, blast+) 253done 254 255 256lemma Spy_analz_shrK [simp]: 257 "evs \<in> bankerberos \<Longrightarrow> (Key (shrK A) \<in> analz (spies evs)) = (A \<in> bad)" 258apply auto 259done 260 261lemma Spy_see_shrK_D [dest!]: 262 "\<lbrakk> Key (shrK A) \<in> parts (spies evs); 263 evs \<in> bankerberos \<rbrakk> \<Longrightarrow> A\<in>bad" 264apply (blast dest: Spy_see_shrK) 265done 266 267lemmas Spy_analz_shrK_D = analz_subset_parts [THEN subsetD, THEN Spy_see_shrK_D, dest!] 268 269 270text\<open>Nobody can have used non-existent keys!\<close> 271lemma new_keys_not_used [simp]: 272 "\<lbrakk>Key K \<notin> used evs; K \<in> symKeys; evs \<in> bankerberos\<rbrakk> 273 \<Longrightarrow> K \<notin> keysFor (parts (spies evs))" 274apply (erule rev_mp) 275apply (erule bankerberos.induct) 276apply (frule_tac [7] Oops_parts_spies) 277apply (frule_tac [5] BK3_msg_in_parts_spies, simp_all) 278txt\<open>Fake\<close> 279apply (force dest!: keysFor_parts_insert) 280txt\<open>BK2, BK3, BK4\<close> 281apply (force dest!: analz_shrK_Decrypt)+ 282done 283 284subsection\<open>Lemmas concerning the form of items passed in messages\<close> 285 286text\<open>Describes the form of K, X and K' when the Server sends this message.\<close> 287lemma Says_Server_message_form: 288 "\<lbrakk> Says Server A (Crypt K' \<lbrace>Number Tk, Agent B, Key K, Ticket\<rbrace>) 289 \<in> set evs; evs \<in> bankerberos \<rbrakk> 290 \<Longrightarrow> K' = shrK A \<and> K \<notin> range shrK \<and> 291 Ticket = (Crypt (shrK B) \<lbrace>Number Tk, Agent A, Key K\<rbrace>) \<and> 292 Key K \<notin> used(before 293 Says Server A (Crypt K' \<lbrace>Number Tk, Agent B, Key K, Ticket\<rbrace>) 294 on evs) \<and> 295 Tk = CT(before 296 Says Server A (Crypt K' \<lbrace>Number Tk, Agent B, Key K, Ticket\<rbrace>) 297 on evs)" 298apply (unfold before_def) 299apply (erule rev_mp) 300apply (erule bankerberos.induct, simp_all add: takeWhile_tail) 301apply auto 302 apply (metis length_rev set_rev takeWhile_void used_evs_rev)+ 303done 304 305 306text\<open>If the encrypted message appears then it originated with the Server 307 PROVIDED that A is NOT compromised! 308 This allows A to verify freshness of the session key. 309\<close> 310lemma Kab_authentic: 311 "\<lbrakk> Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, X\<rbrace> 312 \<in> parts (spies evs); 313 A \<notin> bad; evs \<in> bankerberos \<rbrakk> 314 \<Longrightarrow> Says Server A (Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, X\<rbrace>) 315 \<in> set evs" 316apply (erule rev_mp) 317apply (erule bankerberos.induct) 318apply (frule_tac [7] Oops_parts_spies) 319apply (frule_tac [5] BK3_msg_in_parts_spies, simp_all, blast) 320done 321 322 323text\<open>If the TICKET appears then it originated with the Server\<close> 324text\<open>FRESHNESS OF THE SESSION KEY to B\<close> 325lemma ticket_authentic: 326 "\<lbrakk> Crypt (shrK B) \<lbrace>Number Tk, Agent A, Key K\<rbrace> \<in> parts (spies evs); 327 B \<notin> bad; evs \<in> bankerberos \<rbrakk> 328 \<Longrightarrow> Says Server A 329 (Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, 330 Crypt (shrK B) \<lbrace>Number Tk, Agent A, Key K\<rbrace>\<rbrace>) 331 \<in> set evs" 332apply (erule rev_mp) 333apply (erule bankerberos.induct) 334apply (frule_tac [7] Oops_parts_spies) 335apply (frule_tac [5] BK3_msg_in_parts_spies, simp_all, blast) 336done 337 338 339text\<open>EITHER describes the form of X when the following message is sent, 340 OR reduces it to the Fake case. 341 Use \<open>Says_Server_message_form\<close> if applicable.\<close> 342lemma Says_S_message_form: 343 "\<lbrakk> Says S A (Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, X\<rbrace>) 344 \<in> set evs; 345 evs \<in> bankerberos \<rbrakk> 346 \<Longrightarrow> (K \<notin> range shrK \<and> X = (Crypt (shrK B) \<lbrace>Number Tk, Agent A, Key K\<rbrace>)) 347 | X \<in> analz (spies evs)" 348apply (case_tac "A \<in> bad") 349apply (force dest!: Says_imp_spies [THEN analz.Inj]) 350apply (frule Says_imp_spies [THEN parts.Inj]) 351apply (blast dest!: Kab_authentic Says_Server_message_form) 352done 353 354 355 356(**** 357 The following is to prove theorems of the form 358 359 Key K \<in> analz (insert (Key KAB) (spies evs)) \<Longrightarrow> 360 Key K \<in> analz (spies evs) 361 362 A more general formula must be proved inductively. 363 364****) 365 366text\<open>Session keys are not used to encrypt other session keys\<close> 367lemma analz_image_freshK [rule_format (no_asm)]: 368 "evs \<in> bankerberos \<Longrightarrow> 369 \<forall>K KK. KK \<subseteq> - (range shrK) \<longrightarrow> 370 (Key K \<in> analz (Key`KK \<union> (spies evs))) = 371 (K \<in> KK | Key K \<in> analz (spies evs))" 372apply (erule bankerberos.induct) 373apply (drule_tac [7] Says_Server_message_form) 374apply (erule_tac [5] Says_S_message_form [THEN disjE], analz_freshK, spy_analz, auto) 375done 376 377 378lemma analz_insert_freshK: 379 "\<lbrakk> evs \<in> bankerberos; KAB \<notin> range shrK \<rbrakk> \<Longrightarrow> 380 (Key K \<in> analz (insert (Key KAB) (spies evs))) = 381 (K = KAB | Key K \<in> analz (spies evs))" 382apply (simp only: analz_image_freshK analz_image_freshK_simps) 383done 384 385text\<open>The session key K uniquely identifies the message\<close> 386lemma unique_session_keys: 387 "\<lbrakk> Says Server A 388 (Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, X\<rbrace>) \<in> set evs; 389 Says Server A' 390 (Crypt (shrK A') \<lbrace>Number Tk', Agent B', Key K, X'\<rbrace>) \<in> set evs; 391 evs \<in> bankerberos \<rbrakk> \<Longrightarrow> A=A' \<and> Tk=Tk' \<and> B=B' \<and> X = X'" 392apply (erule rev_mp) 393apply (erule rev_mp) 394apply (erule bankerberos.induct) 395apply (frule_tac [7] Oops_parts_spies) 396apply (frule_tac [5] BK3_msg_in_parts_spies, simp_all) 397txt\<open>BK2: it can't be a new key\<close> 398apply blast 399done 400 401lemma Server_Unique: 402 "\<lbrakk> Says Server A 403 (Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, Ticket\<rbrace>) \<in> set evs; 404 evs \<in> bankerberos \<rbrakk> \<Longrightarrow> 405 Unique Says Server A (Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, Ticket\<rbrace>) 406 on evs" 407apply (erule rev_mp, erule bankerberos.induct, simp_all add: Unique_def) 408apply blast 409done 410 411 412subsection\<open>Non-temporal guarantees, explicitly relying on non-occurrence of 413oops events - refined below by temporal guarantees\<close> 414 415text\<open>Non temporal treatment of confidentiality\<close> 416 417text\<open>Lemma: the session key sent in msg BK2 would be lost by oops 418 if the spy could see it!\<close> 419lemma lemma_conf [rule_format (no_asm)]: 420 "\<lbrakk> A \<notin> bad; B \<notin> bad; evs \<in> bankerberos \<rbrakk> 421 \<Longrightarrow> Says Server A 422 (Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, 423 Crypt (shrK B) \<lbrace>Number Tk, Agent A, Key K\<rbrace>\<rbrace>) 424 \<in> set evs \<longrightarrow> 425 Key K \<in> analz (spies evs) \<longrightarrow> Notes Spy \<lbrace>Number Tk, Key K\<rbrace> \<in> set evs" 426apply (erule bankerberos.induct) 427apply (frule_tac [7] Says_Server_message_form) 428apply (frule_tac [5] Says_S_message_form [THEN disjE]) 429apply (simp_all (no_asm_simp) add: analz_insert_eq analz_insert_freshK pushes) 430txt\<open>Fake\<close> 431apply spy_analz 432txt\<open>BK2\<close> 433apply (blast intro: parts_insertI) 434txt\<open>BK3\<close> 435apply (case_tac "Aa \<in> bad") 436 prefer 2 apply (blast dest: Kab_authentic unique_session_keys) 437apply (blast dest: Says_imp_spies [THEN analz.Inj] Crypt_Spy_analz_bad elim!: MPair_analz) 438txt\<open>Oops\<close> 439apply (blast dest: unique_session_keys) 440done 441 442 443text\<open>Confidentiality for the Server: Spy does not see the keys sent in msg BK2 444as long as they have not expired.\<close> 445lemma Confidentiality_S: 446 "\<lbrakk> Says Server A 447 (Crypt K' \<lbrace>Number Tk, Agent B, Key K, Ticket\<rbrace>) \<in> set evs; 448 Notes Spy \<lbrace>Number Tk, Key K\<rbrace> \<notin> set evs; 449 A \<notin> bad; B \<notin> bad; evs \<in> bankerberos 450 \<rbrakk> \<Longrightarrow> Key K \<notin> analz (spies evs)" 451apply (frule Says_Server_message_form, assumption) 452apply (blast intro: lemma_conf) 453done 454 455text\<open>Confidentiality for Alice\<close> 456lemma Confidentiality_A: 457 "\<lbrakk> Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, X\<rbrace> \<in> parts (spies evs); 458 Notes Spy \<lbrace>Number Tk, Key K\<rbrace> \<notin> set evs; 459 A \<notin> bad; B \<notin> bad; evs \<in> bankerberos 460 \<rbrakk> \<Longrightarrow> Key K \<notin> analz (spies evs)" 461apply (blast dest!: Kab_authentic Confidentiality_S) 462done 463 464text\<open>Confidentiality for Bob\<close> 465lemma Confidentiality_B: 466 "\<lbrakk> Crypt (shrK B) \<lbrace>Number Tk, Agent A, Key K\<rbrace> 467 \<in> parts (spies evs); 468 Notes Spy \<lbrace>Number Tk, Key K\<rbrace> \<notin> set evs; 469 A \<notin> bad; B \<notin> bad; evs \<in> bankerberos 470 \<rbrakk> \<Longrightarrow> Key K \<notin> analz (spies evs)" 471apply (blast dest!: ticket_authentic Confidentiality_S) 472done 473 474text\<open>Non temporal treatment of authentication\<close> 475 476text\<open>Lemmas \<open>lemma_A\<close> and \<open>lemma_B\<close> in fact are common to both temporal and non-temporal treatments\<close> 477lemma lemma_A [rule_format]: 478 "\<lbrakk> A \<notin> bad; B \<notin> bad; evs \<in> bankerberos \<rbrakk> 479 \<Longrightarrow> 480 Key K \<notin> analz (spies evs) \<longrightarrow> 481 Says Server A (Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, X\<rbrace>) 482 \<in> set evs \<longrightarrow> 483 Crypt K \<lbrace>Agent A, Number Ta\<rbrace> \<in> parts (spies evs) \<longrightarrow> 484 Says A B \<lbrace>X, Crypt K \<lbrace>Agent A, Number Ta\<rbrace>\<rbrace> 485 \<in> set evs" 486apply (erule bankerberos.induct) 487apply (frule_tac [7] Oops_parts_spies) 488apply (frule_tac [5] Says_S_message_form) 489apply (frule_tac [6] BK3_msg_in_parts_spies, analz_mono_contra) 490apply (simp_all (no_asm_simp) add: all_conj_distrib) 491txt\<open>Fake\<close> 492apply blast 493txt\<open>BK2\<close> 494apply (force dest: Crypt_imp_invKey_keysFor) 495txt\<open>BK3\<close> 496apply (blast dest: Kab_authentic unique_session_keys) 497done 498 499lemma lemma_B [rule_format]: 500 "\<lbrakk> B \<notin> bad; evs \<in> bankerberos \<rbrakk> 501 \<Longrightarrow> Key K \<notin> analz (spies evs) \<longrightarrow> 502 Says Server A (Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, X\<rbrace>) 503 \<in> set evs \<longrightarrow> 504 Crypt K (Number Ta) \<in> parts (spies evs) \<longrightarrow> 505 Says B A (Crypt K (Number Ta)) \<in> set evs" 506apply (erule bankerberos.induct) 507apply (frule_tac [7] Oops_parts_spies) 508apply (frule_tac [5] Says_S_message_form) 509apply (drule_tac [6] BK3_msg_in_parts_spies, analz_mono_contra) 510apply (simp_all (no_asm_simp) add: all_conj_distrib) 511txt\<open>Fake\<close> 512apply blast 513txt\<open>BK2\<close> 514apply (force dest: Crypt_imp_invKey_keysFor) 515txt\<open>BK4\<close> 516apply (blast dest: ticket_authentic unique_session_keys 517 Says_imp_spies [THEN analz.Inj] Crypt_Spy_analz_bad) 518done 519 520 521text\<open>The "r" suffix indicates theorems where the confidentiality assumptions are relaxed by the corresponding arguments.\<close> 522 523 524text\<open>Authentication of A to B\<close> 525lemma B_authenticates_A_r: 526 "\<lbrakk> Crypt K \<lbrace>Agent A, Number Ta\<rbrace> \<in> parts (spies evs); 527 Crypt (shrK B) \<lbrace>Number Tk, Agent A, Key K\<rbrace> \<in> parts (spies evs); 528 Notes Spy \<lbrace>Number Tk, Key K\<rbrace> \<notin> set evs; 529 A \<notin> bad; B \<notin> bad; evs \<in> bankerberos \<rbrakk> 530 \<Longrightarrow> Says A B \<lbrace>Crypt (shrK B) \<lbrace>Number Tk, Agent A, Key K\<rbrace>, 531 Crypt K \<lbrace>Agent A, Number Ta\<rbrace>\<rbrace> \<in> set evs" 532apply (blast dest!: ticket_authentic 533 intro!: lemma_A 534 elim!: Confidentiality_S [THEN [2] rev_notE]) 535done 536 537 538text\<open>Authentication of B to A\<close> 539lemma A_authenticates_B_r: 540 "\<lbrakk> Crypt K (Number Ta) \<in> parts (spies evs); 541 Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, X\<rbrace> \<in> parts (spies evs); 542 Notes Spy \<lbrace>Number Tk, Key K\<rbrace> \<notin> set evs; 543 A \<notin> bad; B \<notin> bad; evs \<in> bankerberos \<rbrakk> 544 \<Longrightarrow> Says B A (Crypt K (Number Ta)) \<in> set evs" 545apply (blast dest!: Kab_authentic 546 intro!: lemma_B elim!: Confidentiality_S [THEN [2] rev_notE]) 547done 548 549lemma B_authenticates_A: 550 "\<lbrakk> Crypt K \<lbrace>Agent A, Number Ta\<rbrace> \<in> parts (spies evs); 551 Crypt (shrK B) \<lbrace>Number Tk, Agent A, Key K\<rbrace> \<in> parts (spies evs); 552 Key K \<notin> analz (spies evs); 553 A \<notin> bad; B \<notin> bad; evs \<in> bankerberos \<rbrakk> 554 \<Longrightarrow> Says A B \<lbrace>Crypt (shrK B) \<lbrace>Number Tk, Agent A, Key K\<rbrace>, 555 Crypt K \<lbrace>Agent A, Number Ta\<rbrace>\<rbrace> \<in> set evs" 556apply (blast dest!: ticket_authentic intro!: lemma_A) 557done 558 559lemma A_authenticates_B: 560 "\<lbrakk> Crypt K (Number Ta) \<in> parts (spies evs); 561 Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, X\<rbrace> \<in> parts (spies evs); 562 Key K \<notin> analz (spies evs); 563 A \<notin> bad; B \<notin> bad; evs \<in> bankerberos \<rbrakk> 564 \<Longrightarrow> Says B A (Crypt K (Number Ta)) \<in> set evs" 565apply (blast dest!: Kab_authentic intro!: lemma_B) 566done 567 568subsection\<open>Temporal guarantees, relying on a temporal check that insures that 569no oops event occurred. These are available in the sense of goal availability\<close> 570 571 572text\<open>Temporal treatment of confidentiality\<close> 573 574text\<open>Lemma: the session key sent in msg BK2 would be EXPIRED 575 if the spy could see it!\<close> 576lemma lemma_conf_temporal [rule_format (no_asm)]: 577 "\<lbrakk> A \<notin> bad; B \<notin> bad; evs \<in> bankerberos \<rbrakk> 578 \<Longrightarrow> Says Server A 579 (Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, 580 Crypt (shrK B) \<lbrace>Number Tk, Agent A, Key K\<rbrace>\<rbrace>) 581 \<in> set evs \<longrightarrow> 582 Key K \<in> analz (spies evs) \<longrightarrow> expiredK Tk evs" 583apply (erule bankerberos.induct) 584apply (frule_tac [7] Says_Server_message_form) 585apply (frule_tac [5] Says_S_message_form [THEN disjE]) 586apply (simp_all (no_asm_simp) add: less_SucI analz_insert_eq analz_insert_freshK pushes) 587txt\<open>Fake\<close> 588apply spy_analz 589txt\<open>BK2\<close> 590apply (blast intro: parts_insertI less_SucI) 591txt\<open>BK3\<close> 592apply (metis Crypt_Spy_analz_bad Kab_authentic Says_imp_analz_Spy 593 Says_imp_parts_knows_Spy analz.Snd less_SucI unique_session_keys) 594txt\<open>Oops: PROOF FAILS if unsafe intro below\<close> 595apply (blast dest: unique_session_keys intro!: less_SucI) 596done 597 598 599text\<open>Confidentiality for the Server: Spy does not see the keys sent in msg BK2 600as long as they have not expired.\<close> 601lemma Confidentiality_S_temporal: 602 "\<lbrakk> Says Server A 603 (Crypt K' \<lbrace>Number T, Agent B, Key K, X\<rbrace>) \<in> set evs; 604 \<not> expiredK T evs; 605 A \<notin> bad; B \<notin> bad; evs \<in> bankerberos 606 \<rbrakk> \<Longrightarrow> Key K \<notin> analz (spies evs)" 607apply (frule Says_Server_message_form, assumption) 608apply (blast intro: lemma_conf_temporal) 609done 610 611text\<open>Confidentiality for Alice\<close> 612lemma Confidentiality_A_temporal: 613 "\<lbrakk> Crypt (shrK A) \<lbrace>Number T, Agent B, Key K, X\<rbrace> \<in> parts (spies evs); 614 \<not> expiredK T evs; 615 A \<notin> bad; B \<notin> bad; evs \<in> bankerberos 616 \<rbrakk> \<Longrightarrow> Key K \<notin> analz (spies evs)" 617apply (blast dest!: Kab_authentic Confidentiality_S_temporal) 618done 619 620text\<open>Confidentiality for Bob\<close> 621lemma Confidentiality_B_temporal: 622 "\<lbrakk> Crypt (shrK B) \<lbrace>Number Tk, Agent A, Key K\<rbrace> 623 \<in> parts (spies evs); 624 \<not> expiredK Tk evs; 625 A \<notin> bad; B \<notin> bad; evs \<in> bankerberos 626 \<rbrakk> \<Longrightarrow> Key K \<notin> analz (spies evs)" 627apply (blast dest!: ticket_authentic Confidentiality_S_temporal) 628done 629 630text\<open>Temporal treatment of authentication\<close> 631 632text\<open>Authentication of A to B\<close> 633lemma B_authenticates_A_temporal: 634 "\<lbrakk> Crypt K \<lbrace>Agent A, Number Ta\<rbrace> \<in> parts (spies evs); 635 Crypt (shrK B) \<lbrace>Number Tk, Agent A, Key K\<rbrace> 636 \<in> parts (spies evs); 637 \<not> expiredK Tk evs; 638 A \<notin> bad; B \<notin> bad; evs \<in> bankerberos \<rbrakk> 639 \<Longrightarrow> Says A B \<lbrace>Crypt (shrK B) \<lbrace>Number Tk, Agent A, Key K\<rbrace>, 640 Crypt K \<lbrace>Agent A, Number Ta\<rbrace>\<rbrace> \<in> set evs" 641apply (blast dest!: ticket_authentic 642 intro!: lemma_A 643 elim!: Confidentiality_S_temporal [THEN [2] rev_notE]) 644done 645 646text\<open>Authentication of B to A\<close> 647lemma A_authenticates_B_temporal: 648 "\<lbrakk> Crypt K (Number Ta) \<in> parts (spies evs); 649 Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, X\<rbrace> 650 \<in> parts (spies evs); 651 \<not> expiredK Tk evs; 652 A \<notin> bad; B \<notin> bad; evs \<in> bankerberos \<rbrakk> 653 \<Longrightarrow> Says B A (Crypt K (Number Ta)) \<in> set evs" 654apply (blast dest!: Kab_authentic 655 intro!: lemma_B elim!: Confidentiality_S_temporal [THEN [2] rev_notE]) 656done 657 658subsection\<open>Treatment of the key distribution goal using trace inspection. All 659guarantees are in non-temporal form, hence non available, though their temporal 660form is trivial to derive. These guarantees also convey a stronger form of 661authentication - non-injective agreement on the session key\<close> 662 663 664lemma B_Issues_A: 665 "\<lbrakk> Says B A (Crypt K (Number Ta)) \<in> set evs; 666 Key K \<notin> analz (spies evs); 667 A \<notin> bad; B \<notin> bad; evs \<in> bankerberos \<rbrakk> 668 \<Longrightarrow> B Issues A with (Crypt K (Number Ta)) on evs" 669apply (simp (no_asm) add: Issues_def) 670apply (rule exI) 671apply (rule conjI, assumption) 672apply (simp (no_asm)) 673apply (erule rev_mp) 674apply (erule rev_mp) 675apply (erule bankerberos.induct, analz_mono_contra) 676apply (simp_all (no_asm_simp)) 677txt\<open>fake\<close> 678apply blast 679txt\<open>K4 obviously is the non-trivial case\<close> 680apply (simp add: takeWhile_tail) 681apply (blast dest: ticket_authentic parts_spies_takeWhile_mono [THEN subsetD] parts_spies_evs_revD2 [THEN subsetD] intro: A_authenticates_B_temporal) 682done 683 684lemma A_authenticates_and_keydist_to_B: 685 "\<lbrakk> Crypt K (Number Ta) \<in> parts (spies evs); 686 Crypt (shrK A) \<lbrace>Number Tk, Agent B, Key K, X\<rbrace> \<in> parts (spies evs); 687 Key K \<notin> analz (spies evs); 688 A \<notin> bad; B \<notin> bad; evs \<in> bankerberos \<rbrakk> 689 \<Longrightarrow> B Issues A with (Crypt K (Number Ta)) on evs" 690apply (blast dest!: A_authenticates_B B_Issues_A) 691done 692 693 694lemma A_Issues_B: 695 "\<lbrakk> Says A B \<lbrace>Ticket, Crypt K \<lbrace>Agent A, Number Ta\<rbrace>\<rbrace> 696 \<in> set evs; 697 Key K \<notin> analz (spies evs); 698 A \<notin> bad; B \<notin> bad; evs \<in> bankerberos \<rbrakk> 699 \<Longrightarrow> A Issues B with (Crypt K \<lbrace>Agent A, Number Ta\<rbrace>) on evs" 700apply (simp (no_asm) add: Issues_def) 701apply (rule exI) 702apply (rule conjI, assumption) 703apply (simp (no_asm)) 704apply (erule rev_mp) 705apply (erule rev_mp) 706apply (erule bankerberos.induct, analz_mono_contra) 707apply (simp_all (no_asm_simp)) 708txt\<open>fake\<close> 709apply blast 710txt\<open>K3 is the non trivial case\<close> 711apply (simp add: takeWhile_tail) 712apply auto (*Technically unnecessary, merely clarifies the subgoal as it is presemted in the book*) 713apply (blast dest: Kab_authentic Says_Server_message_form parts_spies_takeWhile_mono [THEN subsetD] parts_spies_evs_revD2 [THEN subsetD] 714 intro!: B_authenticates_A) 715done 716 717 718lemma B_authenticates_and_keydist_to_A: 719 "\<lbrakk> Crypt K \<lbrace>Agent A, Number Ta\<rbrace> \<in> parts (spies evs); 720 Crypt (shrK B) \<lbrace>Number Tk, Agent A, Key K\<rbrace> \<in> parts (spies evs); 721 Key K \<notin> analz (spies evs); 722 A \<notin> bad; B \<notin> bad; evs \<in> bankerberos \<rbrakk> 723 \<Longrightarrow> A Issues B with (Crypt K \<lbrace>Agent A, Number Ta\<rbrace>) on evs" 724apply (blast dest: B_authenticates_A A_Issues_B) 725done 726 727 728 729 730end 731