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