converted many HOL/Auth theories to Isar scripts
authorpaulson
Thu Apr 12 12:45:05 2001 +0200 (2001-04-12)
changeset 11251a6816d47f41d
parent 11250 c8bbf4c4bc2d
child 11252 71c00cb091d2
converted many HOL/Auth theories to Isar scripts
src/HOL/Auth/Message.thy
src/HOL/Auth/Message_lemmas.ML
src/HOL/Auth/NS_Shared.thy
src/HOL/Auth/OtwayRees.ML
src/HOL/Auth/OtwayRees.thy
src/HOL/Auth/OtwayRees_AN.ML
src/HOL/Auth/OtwayRees_AN.thy
src/HOL/Auth/OtwayRees_Bad.ML
src/HOL/Auth/OtwayRees_Bad.thy
src/HOL/Auth/WooLam.ML
src/HOL/Auth/WooLam.thy
src/HOL/Auth/Yahalom.ML
src/HOL/Auth/Yahalom.thy
src/HOL/Auth/Yahalom2.ML
src/HOL/Auth/Yahalom2.thy
src/HOL/Auth/Yahalom_Bad.ML
src/HOL/Auth/Yahalom_Bad.thy
src/HOL/IsaMakefile
     1.1 --- a/src/HOL/Auth/Message.thy	Wed Apr 11 11:53:54 2001 +0200
     1.2 +++ b/src/HOL/Auth/Message.thy	Thu Apr 12 12:45:05 2001 +0200
     1.3 @@ -135,6 +135,8 @@
     1.4  
     1.5  use "Message_lemmas.ML"
     1.6  
     1.7 +lemmas analz_into_parts = analz_subset_parts [THEN subsetD, standard]
     1.8 +
     1.9  lemma Fake_parts_insert_in_Un:
    1.10       "[|Z \<in> parts (insert X H);  X: synth (analz H)|] 
    1.11        ==> Z \<in>  synth (analz H) \<union> parts H";
     2.1 --- a/src/HOL/Auth/Message_lemmas.ML	Wed Apr 11 11:53:54 2001 +0200
     2.2 +++ b/src/HOL/Auth/Message_lemmas.ML	Thu Apr 12 12:45:05 2001 +0200
     2.3 @@ -50,7 +50,7 @@
     2.4  by Auto_tac;
     2.5  qed "Friend_image_eq";
     2.6  
     2.7 -Goal "(Key x \\<in> Key`A) = (x:A)";
     2.8 +Goal "(Key x \\<in> Key`A) = (x\\<in>A)";
     2.9  by Auto_tac;
    2.10  qed "Key_image_eq";
    2.11  
    2.12 @@ -82,12 +82,12 @@
    2.13  by (Blast_tac 1);
    2.14  qed "keysFor_Un";
    2.15  
    2.16 -Goalw [keysFor_def] "keysFor (UN i:A. H i) = (UN i:A. keysFor (H i))";
    2.17 +Goalw [keysFor_def] "keysFor (\\<Union>i\\<in>A. H i) = (\\<Union>i\\<in>A. keysFor (H i))";
    2.18  by (Blast_tac 1);
    2.19  qed "keysFor_UN";
    2.20  
    2.21  (*Monotonicity*)
    2.22 -Goalw [keysFor_def] "G<=H ==> keysFor(G) <= keysFor(H)";
    2.23 +Goalw [keysFor_def] "G\\<subseteq>H ==> keysFor(G) \\<subseteq> keysFor(H)";
    2.24  by (Blast_tac 1);
    2.25  qed "keysFor_mono";
    2.26  
    2.27 @@ -154,7 +154,7 @@
    2.28    MPair_parts is left as SAFE because it speeds up proofs.
    2.29    The Crypt rule is normally kept UNSAFE to avoid breaking up certificates.*)
    2.30  
    2.31 -Goal "H <= parts(H)";
    2.32 +Goal "H \\<subseteq> parts(H)";
    2.33  by (Blast_tac 1);
    2.34  qed "parts_increasing";
    2.35  
    2.36 @@ -167,13 +167,13 @@
    2.37  qed "parts_empty";
    2.38  Addsimps [parts_empty];
    2.39  
    2.40 -Goal "X: parts{} ==> P";
    2.41 +Goal "X\\<in> parts{} ==> P";
    2.42  by (Asm_full_simp_tac 1);
    2.43  qed "parts_emptyE";
    2.44  AddSEs [parts_emptyE];
    2.45  
    2.46  (*WARNING: loops if H = {Y}, therefore must not be repeated!*)
    2.47 -Goal "X: parts H ==> EX Y:H. X: parts {Y}";
    2.48 +Goal "X\\<in> parts H ==> \\<exists>Y\\<in>H. X\\<in> parts {Y}";
    2.49  by (etac parts.induct 1);
    2.50  by (ALLGOALS Blast_tac);
    2.51  qed "parts_singleton";
    2.52 @@ -181,11 +181,11 @@
    2.53  
    2.54  (** Unions **)
    2.55  
    2.56 -Goal "parts(G) Un parts(H) <= parts(G Un H)";
    2.57 +Goal "parts(G) Un parts(H) \\<subseteq> parts(G Un H)";
    2.58  by (REPEAT (ares_tac [Un_least, parts_mono, Un_upper1, Un_upper2] 1));
    2.59  val parts_Un_subset1 = result();
    2.60  
    2.61 -Goal "parts(G Un H) <= parts(G) Un parts(H)";
    2.62 +Goal "parts(G Un H) \\<subseteq> parts(G) Un parts(H)";
    2.63  by (rtac subsetI 1);
    2.64  by (etac parts.induct 1);
    2.65  by (ALLGOALS Blast_tac);
    2.66 @@ -207,17 +207,17 @@
    2.67  by (simp_tac (simpset() addsimps [parts_insert RS sym]) 1);
    2.68  qed "parts_insert2";
    2.69  
    2.70 -Goal "(UN x:A. parts(H x)) <= parts(UN x:A. H x)";
    2.71 +Goal "(\\<Union>x\\<in>A. parts(H x)) \\<subseteq> parts(\\<Union>x\\<in>A. H x)";
    2.72  by (REPEAT (ares_tac [UN_least, parts_mono, UN_upper] 1));
    2.73  val parts_UN_subset1 = result();
    2.74  
    2.75 -Goal "parts(UN x:A. H x) <= (UN x:A. parts(H x))";
    2.76 +Goal "parts(\\<Union>x\\<in>A. H x) \\<subseteq> (\\<Union>x\\<in>A. parts(H x))";
    2.77  by (rtac subsetI 1);
    2.78  by (etac parts.induct 1);
    2.79  by (ALLGOALS Blast_tac);
    2.80  val parts_UN_subset2 = result();
    2.81  
    2.82 -Goal "parts(UN x:A. H x) = (UN x:A. parts(H x))";
    2.83 +Goal "parts(\\<Union>x\\<in>A. H x) = (\\<Union>x\\<in>A. parts(H x))";
    2.84  by (REPEAT (ares_tac [equalityI, parts_UN_subset1, parts_UN_subset2] 1));
    2.85  qed "parts_UN";
    2.86  
    2.87 @@ -227,13 +227,13 @@
    2.88  AddSEs [parts_Un RS equalityD1 RS subsetD RS UnE,
    2.89  	parts_UN RS equalityD1 RS subsetD RS UN_E];
    2.90  
    2.91 -Goal "insert X (parts H) <= parts(insert X H)";
    2.92 +Goal "insert X (parts H) \\<subseteq> parts(insert X H)";
    2.93  by (blast_tac (claset() addIs [impOfSubs parts_mono]) 1);
    2.94  qed "parts_insert_subset";
    2.95  
    2.96  (** Idempotence and transitivity **)
    2.97  
    2.98 -Goal "X: parts (parts H) ==> X: parts H";
    2.99 +Goal "X\\<in> parts (parts H) ==> X\\<in> parts H";
   2.100  by (etac parts.induct 1);
   2.101  by (ALLGOALS Blast_tac);
   2.102  qed "parts_partsD";
   2.103 @@ -244,19 +244,19 @@
   2.104  qed "parts_idem";
   2.105  Addsimps [parts_idem];
   2.106  
   2.107 -Goal "[| X: parts G;  G <= parts H |] ==> X: parts H";
   2.108 +Goal "[| X\\<in> parts G;  G \\<subseteq> parts H |] ==> X\\<in> parts H";
   2.109  by (dtac parts_mono 1);
   2.110  by (Blast_tac 1);
   2.111  qed "parts_trans";
   2.112  
   2.113  (*Cut*)
   2.114 -Goal "[| Y: parts (insert X G);  X: parts H |] \
   2.115 -\              ==> Y: parts (G Un H)";
   2.116 +Goal "[| Y\\<in> parts (insert X G);  X\\<in> parts H |] \
   2.117 +\              ==> Y\\<in> parts (G Un H)";
   2.118  by (etac parts_trans 1);
   2.119  by Auto_tac;
   2.120  qed "parts_cut";
   2.121  
   2.122 -Goal "X: parts H ==> parts (insert X H) = parts H";
   2.123 +Goal "X\\<in> parts H ==> parts (insert X H) = parts H";
   2.124  by (fast_tac (claset() addSDs [parts_cut]
   2.125                         addIs  [parts_insertI] 
   2.126                         addss (simpset())) 1);
   2.127 @@ -326,7 +326,7 @@
   2.128  
   2.129  
   2.130  (*In any message, there is an upper bound N on its greatest nonce.*)
   2.131 -Goal "EX N. ALL n. N<=n --> Nonce n \\<notin> parts {msg}";
   2.132 +Goal "\\<exists>N. \\<forall>n. N\\<le>n --> Nonce n \\<notin> parts {msg}";
   2.133  by (induct_tac "msg" 1);
   2.134  by (ALLGOALS (asm_simp_tac (simpset() addsimps [exI, parts_insert2])));
   2.135  (*MPair case: blast_tac works out the necessary sum itself!*)
   2.136 @@ -350,11 +350,11 @@
   2.137  
   2.138  AddSEs [MPair_analz];     (*Making it safe speeds up proofs*)
   2.139  
   2.140 -Goal "H <= analz(H)";
   2.141 +Goal "H \\<subseteq> analz(H)";
   2.142  by (Blast_tac 1);
   2.143  qed "analz_increasing";
   2.144  
   2.145 -Goal "analz H <= parts H";
   2.146 +Goal "analz H \\<subseteq> parts H";
   2.147  by (rtac subsetI 1);
   2.148  by (etac analz.induct 1);
   2.149  by (ALLGOALS Blast_tac);
   2.150 @@ -391,11 +391,11 @@
   2.151  
   2.152  (*Converse fails: we can analz more from the union than from the 
   2.153    separate parts, as a key in one might decrypt a message in the other*)
   2.154 -Goal "analz(G) Un analz(H) <= analz(G Un H)";
   2.155 +Goal "analz(G) Un analz(H) \\<subseteq> analz(G Un H)";
   2.156  by (REPEAT (ares_tac [Un_least, analz_mono, Un_upper1, Un_upper2] 1));
   2.157  qed "analz_Un";
   2.158  
   2.159 -Goal "insert X (analz H) <= analz(insert X H)";
   2.160 +Goal "insert X (analz H) \\<subseteq> analz(insert X H)";
   2.161  by (blast_tac (claset() addIs [impOfSubs analz_mono]) 1);
   2.162  qed "analz_insert";
   2.163  
   2.164 @@ -447,7 +447,7 @@
   2.165  qed "analz_insert_Crypt";
   2.166  
   2.167  Goal "Key (invKey K) \\<in> analz H ==>  \
   2.168 -\              analz (insert (Crypt K X) H) <= \
   2.169 +\              analz (insert (Crypt K X) H) \\<subseteq> \
   2.170  \              insert (Crypt K X) (analz (insert X H))";
   2.171  by (rtac subsetI 1);
   2.172  by (eres_inst_tac [("xa","x")] analz.induct 1);
   2.173 @@ -455,7 +455,7 @@
   2.174  val lemma1 = result();
   2.175  
   2.176  Goal "Key (invKey K) \\<in> analz H ==>  \
   2.177 -\              insert (Crypt K X) (analz (insert X H)) <= \
   2.178 +\              insert (Crypt K X) (analz (insert X H)) \\<subseteq> \
   2.179  \              analz (insert (Crypt K X) H)";
   2.180  by Auto_tac;
   2.181  by (eres_inst_tac [("xa","x")] analz.induct 1);
   2.182 @@ -487,7 +487,7 @@
   2.183            analz_insert_Hash, analz_insert_MPair, analz_Crypt_if];
   2.184  
   2.185  (*This rule supposes "for the sake of argument" that we have the key.*)
   2.186 -Goal  "analz (insert (Crypt K X) H) <=  \
   2.187 +Goal  "analz (insert (Crypt K X) H) \\<subseteq>  \
   2.188  \          insert (Crypt K X) (analz (insert X H))";
   2.189  by (rtac subsetI 1);
   2.190  by (etac analz.induct 1);
   2.191 @@ -506,7 +506,7 @@
   2.192  
   2.193  (** Idempotence and transitivity **)
   2.194  
   2.195 -Goal "X: analz (analz H) ==> X: analz H";
   2.196 +Goal "X\\<in> analz (analz H) ==> X\\<in> analz H";
   2.197  by (etac analz.induct 1);
   2.198  by (ALLGOALS Blast_tac);
   2.199  qed "analz_analzD";
   2.200 @@ -517,13 +517,13 @@
   2.201  qed "analz_idem";
   2.202  Addsimps [analz_idem];
   2.203  
   2.204 -Goal "[| X: analz G;  G <= analz H |] ==> X: analz H";
   2.205 +Goal "[| X\\<in> analz G;  G \\<subseteq> analz H |] ==> X\\<in> analz H";
   2.206  by (dtac analz_mono 1);
   2.207  by (Blast_tac 1);
   2.208  qed "analz_trans";
   2.209  
   2.210  (*Cut; Lemma 2 of Lowe*)
   2.211 -Goal "[| Y: analz (insert X H);  X: analz H |] ==> Y: analz H";
   2.212 +Goal "[| Y\\<in> analz (insert X H);  X\\<in> analz H |] ==> Y\\<in> analz H";
   2.213  by (etac analz_trans 1);
   2.214  by (Blast_tac 1);
   2.215  qed "analz_cut";
   2.216 @@ -535,15 +535,15 @@
   2.217  (*This rewrite rule helps in the simplification of messages that involve
   2.218    the forwarding of unknown components (X).  Without it, removing occurrences
   2.219    of X can be very complicated. *)
   2.220 -Goal "X: analz H ==> analz (insert X H) = analz H";
   2.221 +Goal "X\\<in> analz H ==> analz (insert X H) = analz H";
   2.222  by (blast_tac (claset() addIs [analz_cut, analz_insertI]) 1);
   2.223  qed "analz_insert_eq";
   2.224  
   2.225  
   2.226  (** A congruence rule for "analz" **)
   2.227  
   2.228 -Goal "[| analz G <= analz G'; analz H <= analz H' \
   2.229 -\              |] ==> analz (G Un H) <= analz (G' Un H')";
   2.230 +Goal "[| analz G \\<subseteq> analz G'; analz H \\<subseteq> analz H' \
   2.231 +\              |] ==> analz (G Un H) \\<subseteq> analz (G' Un H')";
   2.232  by (Clarify_tac 1);
   2.233  by (etac analz.induct 1);
   2.234  by (ALLGOALS (best_tac (claset() addIs [analz_mono RS subsetD])));
   2.235 @@ -562,20 +562,19 @@
   2.236  qed "analz_insert_cong";
   2.237  
   2.238  (*If there are no pairs or encryptions then analz does nothing*)
   2.239 -Goal "[| ALL X Y. {|X,Y|} \\<notin> H;  ALL X K. Crypt K X \\<notin> H |] ==> \
   2.240 -\         analz H = H";
   2.241 +Goal "[| \\<forall>X Y. {|X,Y|} \\<notin> H;  \\<forall>X K. Crypt K X \\<notin> H |] ==> analz H = H";
   2.242  by Safe_tac;
   2.243  by (etac analz.induct 1);
   2.244  by (ALLGOALS Blast_tac);
   2.245  qed "analz_trivial";
   2.246  
   2.247  (*These two are obsolete (with a single Spy) but cost little to prove...*)
   2.248 -Goal "X: analz (UN i:A. analz (H i)) ==> X: analz (UN i:A. H i)";
   2.249 +Goal "X\\<in> analz (\\<Union>i\\<in>A. analz (H i)) ==> X\\<in> analz (\\<Union>i\\<in>A. H i)";
   2.250  by (etac analz.induct 1);
   2.251  by (ALLGOALS (blast_tac (claset() addIs [impOfSubs analz_mono])));
   2.252  val lemma = result();
   2.253  
   2.254 -Goal "analz (UN i:A. analz (H i)) = analz (UN i:A. H i)";
   2.255 +Goal "analz (\\<Union>i\\<in>A. analz (H i)) = analz (\\<Union>i\\<in>A. H i)";
   2.256  by (blast_tac (claset() addIs [lemma, impOfSubs analz_mono]) 1);
   2.257  qed "analz_UN_analz";
   2.258  Addsimps [analz_UN_analz];
   2.259 @@ -583,7 +582,7 @@
   2.260  
   2.261  (**** Inductive relation "synth" ****)
   2.262  
   2.263 -Goal "H <= synth(H)";
   2.264 +Goal "H \\<subseteq> synth(H)";
   2.265  by (Blast_tac 1);
   2.266  qed "synth_increasing";
   2.267  
   2.268 @@ -591,17 +590,17 @@
   2.269  
   2.270  (*Converse fails: we can synth more from the union than from the 
   2.271    separate parts, building a compound message using elements of each.*)
   2.272 -Goal "synth(G) Un synth(H) <= synth(G Un H)";
   2.273 +Goal "synth(G) Un synth(H) \\<subseteq> synth(G Un H)";
   2.274  by (REPEAT (ares_tac [Un_least, synth_mono, Un_upper1, Un_upper2] 1));
   2.275  qed "synth_Un";
   2.276  
   2.277 -Goal "insert X (synth H) <= synth(insert X H)";
   2.278 +Goal "insert X (synth H) \\<subseteq> synth(insert X H)";
   2.279  by (blast_tac (claset() addIs [impOfSubs synth_mono]) 1);
   2.280  qed "synth_insert";
   2.281  
   2.282  (** Idempotence and transitivity **)
   2.283  
   2.284 -Goal "X: synth (synth H) ==> X: synth H";
   2.285 +Goal "X\\<in> synth (synth H) ==> X\\<in> synth H";
   2.286  by (etac synth.induct 1);
   2.287  by (ALLGOALS Blast_tac);
   2.288  qed "synth_synthD";
   2.289 @@ -611,13 +610,13 @@
   2.290  by (Blast_tac 1);
   2.291  qed "synth_idem";
   2.292  
   2.293 -Goal "[| X: synth G;  G <= synth H |] ==> X: synth H";
   2.294 +Goal "[| X\\<in> synth G;  G \\<subseteq> synth H |] ==> X\\<in> synth H";
   2.295  by (dtac synth_mono 1);
   2.296  by (Blast_tac 1);
   2.297  qed "synth_trans";
   2.298  
   2.299  (*Cut; Lemma 2 of Lowe*)
   2.300 -Goal "[| Y: synth (insert X H);  X: synth H |] ==> Y: synth H";
   2.301 +Goal "[| Y\\<in> synth (insert X H);  X\\<in> synth H |] ==> Y\\<in> synth H";
   2.302  by (etac synth_trans 1);
   2.303  by (Blast_tac 1);
   2.304  qed "synth_cut";
   2.305 @@ -688,23 +687,23 @@
   2.306  
   2.307  (** For reasoning about the Fake rule in traces **)
   2.308  
   2.309 -Goal "X: G ==> parts(insert X H) <= parts G Un parts H";
   2.310 +Goal "X\\<in> G ==> parts(insert X H) \\<subseteq> parts G Un parts H";
   2.311  by (rtac ([parts_mono, parts_Un_subset2] MRS subset_trans) 1);
   2.312  by (Blast_tac 1);
   2.313  qed "parts_insert_subset_Un";
   2.314  
   2.315  (*More specifically for Fake.  Very occasionally we could do with a version
   2.316 -  of the form  parts{X} <= synth (analz H) Un parts H *)
   2.317 -Goal "X: synth (analz H) ==> \
   2.318 -\     parts (insert X H) <= synth (analz H) Un parts H";
   2.319 +  of the form  parts{X} \\<subseteq> synth (analz H) Un parts H *)
   2.320 +Goal "X\\<in> synth (analz H) ==> \
   2.321 +\     parts (insert X H) \\<subseteq> synth (analz H) Un parts H";
   2.322  by (dtac parts_insert_subset_Un 1);
   2.323  by (Full_simp_tac 1);
   2.324  by (Blast_tac 1);
   2.325  qed "Fake_parts_insert";
   2.326  
   2.327  (*H is sometimes (Key ` KK Un spies evs), so can't put G=H*)
   2.328 -Goal "X: synth (analz G) ==> \
   2.329 -\     analz (insert X H) <= synth (analz G) Un analz (G Un H)";
   2.330 +Goal "X\\<in> synth (analz G) ==> \
   2.331 +\     analz (insert X H) \\<subseteq> synth (analz G) Un analz (G Un H)";
   2.332  by (rtac subsetI 1);
   2.333  by (subgoal_tac "x \\<in> analz (synth (analz G) Un H)" 1);
   2.334  by (blast_tac (claset() addIs [impOfSubs analz_mono,
   2.335 @@ -713,11 +712,11 @@
   2.336  by (Blast_tac 1);
   2.337  qed "Fake_analz_insert";
   2.338  
   2.339 -Goal "(X: analz H & X: parts H) = (X: analz H)";
   2.340 +Goal "(X\\<in> analz H & X\\<in> parts H) = (X\\<in> analz H)";
   2.341  by (blast_tac (claset() addIs [impOfSubs analz_subset_parts]) 1);
   2.342  val analz_conj_parts = result();
   2.343  
   2.344 -Goal "(X: analz H | X: parts H) = (X: parts H)";
   2.345 +Goal "(X\\<in> analz H | X\\<in> parts H) = (X\\<in> parts H)";
   2.346  by (blast_tac (claset() addIs [impOfSubs analz_subset_parts]) 1);
   2.347  val analz_disj_parts = result();
   2.348  
     3.1 --- a/src/HOL/Auth/NS_Shared.thy	Wed Apr 11 11:53:54 2001 +0200
     3.2 +++ b/src/HOL/Auth/NS_Shared.thy	Thu Apr 12 12:45:05 2001 +0200
     3.3 @@ -20,8 +20,8 @@
     3.4  	(*The spy MAY say anything he CAN say.  We do not expect him to
     3.5  	  invent new nonces here, but he can also use NS1.  Common to
     3.6  	  all similar protocols.*)
     3.7 -  Fake: "\<lbrakk>evs \<in> ns_shared;  X \<in> synth (analz (spies evs))\<rbrakk>
     3.8 -	 \<Longrightarrow> Says Spy B X # evs \<in> ns_shared"
     3.9 +  Fake: "\<lbrakk>evsf \<in> ns_shared;  X \<in> synth (analz (spies evsf))\<rbrakk>
    3.10 +	 \<Longrightarrow> Says Spy B X # evsf \<in> ns_shared"
    3.11  
    3.12  	(*Alice initiates a protocol run, requesting to talk to any B*)
    3.13    NS1:  "\<lbrakk>evs1 \<in> ns_shared;  Nonce NA \<notin> used evs1\<rbrakk>
    3.14 @@ -74,10 +74,8 @@
    3.15  
    3.16  declare Says_imp_knows_Spy [THEN parts.Inj, dest]
    3.17  declare parts.Body  [dest]
    3.18 -declare MPair_parts [elim!]    (*can speed up some proofs*)
    3.19 -
    3.20 -declare analz_subset_parts [THEN subsetD, dest]
    3.21 -declare Fake_parts_insert  [THEN subsetD, dest]
    3.22 +declare Fake_parts_insert_in_Un  [dest]
    3.23 +declare analz_into_parts [dest]
    3.24  declare image_eq_UN [simp]  (*accelerates proofs involving nested images*)
    3.25  
    3.26  
    3.27 @@ -123,7 +121,6 @@
    3.28  apply blast+;
    3.29  done
    3.30  
    3.31 -
    3.32  lemma Spy_analz_shrK [simp]:
    3.33       "evs \<in> ns_shared \<Longrightarrow> (Key (shrK A) \<in> analz (spies evs)) = (A \<in> bad)"
    3.34  by auto
    3.35 @@ -310,8 +307,7 @@
    3.36        Crypt K (Nonce NB) \<in> parts (spies evs) \<longrightarrow>
    3.37        Says B A (Crypt K (Nonce NB)) \<in> set evs"
    3.38  apply (erule ns_shared.induct, force, drule_tac [4] NS3_msg_in_parts_spies)
    3.39 -apply analz_mono_contra
    3.40 -apply simp_all
    3.41 +apply (analz_mono_contra, simp_all)
    3.42  apply blast     (*Fake*)
    3.43  (*NS2: contradiction from the assumptions  
    3.44    Key K \<notin> used evs2  and Crypt K (Nonce NB) \<in> parts (spies evs2) *)
     4.1 --- a/src/HOL/Auth/OtwayRees.ML	Wed Apr 11 11:53:54 2001 +0200
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,411 +0,0 @@
     4.4 -(*  Title:      HOL/Auth/OtwayRees
     4.5 -    ID:         $Id$
     4.6 -    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     4.7 -    Copyright   1996  University of Cambridge
     4.8 -
     4.9 -Inductive relation "otway" for the Otway-Rees protocol.
    4.10 -
    4.11 -Version that encrypts Nonce NB
    4.12 -
    4.13 -From page 244 of
    4.14 -  Burrows, Abadi and Needham.  A Logic of Authentication.
    4.15 -  Proc. Royal Soc. 426 (1989)
    4.16 -*)
    4.17 -
    4.18 -AddDs  [Says_imp_knows_Spy RS parts.Inj, parts.Body];
    4.19 -AddDs  [impOfSubs analz_subset_parts, impOfSubs Fake_parts_insert];
    4.20 -
    4.21 -
    4.22 -(*A "possibility property": there are traces that reach the end*)
    4.23 -Goal "B \\<noteq> Server   \
    4.24 -\     ==> \\<exists>K. \\<exists>evs \\<in> otway.          \
    4.25 -\            Says B A {|Nonce NA, Crypt (shrK A) {|Nonce NA, Key K|}|} \
    4.26 -\              \\<in> set evs";
    4.27 -by (REPEAT (resolve_tac [exI,bexI] 1));
    4.28 -by (rtac (otway.Nil RS 
    4.29 -          otway.OR1 RS otway.Reception RS
    4.30 -          otway.OR2 RS otway.Reception RS 
    4.31 -          otway.OR3 RS otway.Reception RS otway.OR4) 2);
    4.32 -by possibility_tac;
    4.33 -result();
    4.34 -
    4.35 -Goal "[| Gets B X \\<in> set evs; evs \\<in> otway |] ==> \\<exists>A. Says A B X \\<in> set evs";
    4.36 -by (etac rev_mp 1);
    4.37 -by (etac otway.induct 1);
    4.38 -by Auto_tac;
    4.39 -qed"Gets_imp_Says";
    4.40 -
    4.41 -(*Must be proved separately for each protocol*)
    4.42 -Goal "[| Gets B X \\<in> set evs; evs \\<in> otway |]  ==> X \\<in> knows Spy evs";
    4.43 -by (blast_tac (claset() addSDs [Gets_imp_Says, Says_imp_knows_Spy]) 1);
    4.44 -qed"Gets_imp_knows_Spy";
    4.45 -AddSDs [Gets_imp_knows_Spy RS parts.Inj];
    4.46 -
    4.47 -
    4.48 -(**** Inductive proofs about otway ****)
    4.49 -
    4.50 -(** For reasoning about the encrypted portion of messages **)
    4.51 -
    4.52 -Goal "[| Gets B {|N, Agent A, Agent B, X|} \\<in> set evs;  evs \\<in> otway |]  \
    4.53 -\     ==> X \\<in> analz (knows Spy evs)";
    4.54 -by (blast_tac (claset() addSDs [Gets_imp_knows_Spy RS analz.Inj]) 1);
    4.55 -qed "OR2_analz_knows_Spy";
    4.56 -
    4.57 -Goal "[| Gets B {|N, X, Crypt (shrK B) X'|} \\<in> set evs;  evs \\<in> otway |] \
    4.58 -\     ==> X \\<in> analz (knows Spy evs)";
    4.59 -by (blast_tac (claset() addSDs [Gets_imp_knows_Spy RS analz.Inj]) 1);
    4.60 -qed "OR4_analz_knows_Spy";
    4.61 -
    4.62 -Goal "Says Server B {|NA, X, Crypt K' {|NB,K|}|} \\<in> set evs \
    4.63 -\     ==> K \\<in> parts (knows Spy evs)";
    4.64 -by (Blast_tac 1);
    4.65 -qed "Oops_parts_knows_Spy";
    4.66 -
    4.67 -bind_thm ("OR2_parts_knows_Spy",
    4.68 -          OR2_analz_knows_Spy RS (impOfSubs analz_subset_parts));
    4.69 -bind_thm ("OR4_parts_knows_Spy",
    4.70 -          OR4_analz_knows_Spy RS (impOfSubs analz_subset_parts));
    4.71 -
    4.72 -(*For proving the easier theorems about X \\<notin> parts (knows Spy evs).*)
    4.73 -fun parts_induct_tac i = 
    4.74 -    etac otway.induct i			THEN 
    4.75 -    ftac Oops_parts_knows_Spy (i+7) THEN
    4.76 -    ftac OR4_parts_knows_Spy (i+6) THEN
    4.77 -    ftac OR2_parts_knows_Spy (i+4) THEN 
    4.78 -    prove_simple_subgoals_tac  i;
    4.79 -
    4.80 -
    4.81 -(** Theorems of the form X \\<notin> parts (knows Spy evs) imply that NOBODY
    4.82 -    sends messages containing X! **)
    4.83 -
    4.84 -(*Spy never sees a good agent's shared key!*)
    4.85 -Goal "evs \\<in> otway ==> (Key (shrK A) \\<in> parts (knows Spy evs)) = (A \\<in> bad)";
    4.86 -by (parts_induct_tac 1);
    4.87 -by (ALLGOALS Blast_tac);
    4.88 -qed "Spy_see_shrK";
    4.89 -Addsimps [Spy_see_shrK];
    4.90 -
    4.91 -Goal "evs \\<in> otway ==> (Key (shrK A) \\<in> analz (knows Spy evs)) = (A \\<in> bad)";
    4.92 -by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset()));
    4.93 -qed "Spy_analz_shrK";
    4.94 -Addsimps [Spy_analz_shrK];
    4.95 -
    4.96 -AddSDs [Spy_see_shrK RSN (2, rev_iffD1), 
    4.97 -	Spy_analz_shrK RSN (2, rev_iffD1)];
    4.98 -
    4.99 -
   4.100 -(*** Proofs involving analz ***)
   4.101 -
   4.102 -(*Describes the form of K and NA when the Server sends this message.  Also
   4.103 -  for Oops case.*)
   4.104 -Goal "[| Says Server B {|NA, X, Crypt (shrK B) {|NB, Key K|}|} \\<in> set evs; \
   4.105 -\        evs \\<in> otway |]                                           \
   4.106 -\     ==> K \\<notin> range shrK & (\\<exists>i. NA = Nonce i) & (\\<exists>j. NB = Nonce j)";
   4.107 -by (etac rev_mp 1);
   4.108 -by (etac otway.induct 1);
   4.109 -by (ALLGOALS Simp_tac);
   4.110 -by (ALLGOALS Blast_tac);
   4.111 -qed "Says_Server_message_form";
   4.112 -
   4.113 -
   4.114 -(*For proofs involving analz.*)
   4.115 -val analz_knows_Spy_tac = 
   4.116 -    dtac OR2_analz_knows_Spy 5 THEN assume_tac 5 THEN 
   4.117 -    dtac OR4_analz_knows_Spy 7 THEN assume_tac 7 THEN
   4.118 -    ftac Says_Server_message_form 8 THEN assume_tac 8 THEN
   4.119 -    REPEAT ((eresolve_tac [exE, conjE] ORELSE' hyp_subst_tac) 8);
   4.120 -
   4.121 -
   4.122 -(****
   4.123 - The following is to prove theorems of the form
   4.124 -
   4.125 -  Key K \\<in> analz (insert (Key KAB) (knows Spy evs)) ==>
   4.126 -  Key K \\<in> analz (knows Spy evs)
   4.127 -
   4.128 - A more general formula must be proved inductively.
   4.129 -****)
   4.130 -
   4.131 -
   4.132 -(** Session keys are not used to encrypt other session keys **)
   4.133 -
   4.134 -(*The equality makes the induction hypothesis easier to apply*)
   4.135 -Goal "evs \\<in> otway ==> ALL K KK. KK <= - (range shrK) -->           \
   4.136 -\                      (Key K \\<in> analz (Key`KK Un (knows Spy evs))) =  \
   4.137 -\                      (K \\<in> KK | Key K \\<in> analz (knows Spy evs))";
   4.138 -by (etac otway.induct 1);
   4.139 -by analz_knows_Spy_tac;
   4.140 -by (REPEAT_FIRST (resolve_tac [allI, impI]));
   4.141 -by (REPEAT_FIRST (rtac analz_image_freshK_lemma));
   4.142 -by (ALLGOALS (asm_simp_tac analz_image_freshK_ss));
   4.143 -(*Fake*) 
   4.144 -by (spy_analz_tac 1);
   4.145 -qed_spec_mp "analz_image_freshK";
   4.146 -
   4.147 -
   4.148 -Goal "[| evs \\<in> otway;  KAB \\<notin> range shrK |]               \
   4.149 -\     ==> Key K \\<in> analz (insert (Key KAB) (knows Spy evs)) =  \
   4.150 -\         (K = KAB | Key K \\<in> analz (knows Spy evs))";
   4.151 -by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
   4.152 -qed "analz_insert_freshK";
   4.153 -
   4.154 -
   4.155 -(*** The Key K uniquely identifies the Server's  message. **)
   4.156 -
   4.157 -Goal "[| Says Server B {|NA, X, Crypt (shrK B) {|NB, K|}|}   \\<in> set evs; \ 
   4.158 -\        Says Server B' {|NA',X',Crypt (shrK B') {|NB',K|}|} \\<in> set evs; \
   4.159 -\        evs \\<in> otway |] ==> X=X' & B=B' & NA=NA' & NB=NB'";
   4.160 -by (etac rev_mp 1);
   4.161 -by (etac rev_mp 1);
   4.162 -by (etac otway.induct 1);
   4.163 -by (ALLGOALS Asm_simp_tac);
   4.164 -(*Remaining cases: OR3 and OR4*)
   4.165 -by (REPEAT (Blast_tac 1)); 
   4.166 -qed "unique_session_keys";
   4.167 -
   4.168 -
   4.169 -(**** Authenticity properties relating to NA ****)
   4.170 -
   4.171 -(*Only OR1 can have caused such a part of a message to appear.*)
   4.172 -Goal "[| A \\<notin> bad;  evs \\<in> otway |]                             \
   4.173 -\ ==> Crypt (shrK A) {|NA, Agent A, Agent B|} \\<in> parts (knows Spy evs) --> \
   4.174 -\     Says A B {|NA, Agent A, Agent B,                      \
   4.175 -\                Crypt (shrK A) {|NA, Agent A, Agent B|}|}  \
   4.176 -\       \\<in> set evs";
   4.177 -by (parts_induct_tac 1);
   4.178 -by (Blast_tac 1);
   4.179 -qed_spec_mp "Crypt_imp_OR1";
   4.180 -
   4.181 -Goal "[| Gets B {|NA, Agent A, Agent B,                      \
   4.182 -\                 Crypt (shrK A) {|NA, Agent A, Agent B|}|} \\<in> set evs; \
   4.183 -\        A \\<notin> bad; evs \\<in> otway |]                             \
   4.184 -\      ==> Says A B {|NA, Agent A, Agent B,                      \
   4.185 -\                     Crypt (shrK A) {|NA, Agent A, Agent B|}|}  \
   4.186 -\            \\<in> set evs";
   4.187 -by (blast_tac (claset() addDs [Crypt_imp_OR1]) 1);
   4.188 -qed"Crypt_imp_OR1_Gets";
   4.189 -
   4.190 -
   4.191 -(** The Nonce NA uniquely identifies A's message. **)
   4.192 -
   4.193 -Goal "[| Crypt (shrK A) {|NA, Agent A, Agent B|}: parts (knows Spy evs); \
   4.194 -\        Crypt (shrK A) {|NA, Agent A, Agent C|}: parts (knows Spy evs); \
   4.195 -\        evs \\<in> otway;  A \\<notin> bad |]                                   \
   4.196 -\     ==> B = C";
   4.197 -by (etac rev_mp 1);
   4.198 -by (etac rev_mp 1);
   4.199 -by (parts_induct_tac 1);
   4.200 -(*Fake, OR1*)
   4.201 -by (REPEAT (Blast_tac 1)); 
   4.202 -qed "unique_NA";
   4.203 -
   4.204 -
   4.205 -(*It is impossible to re-use a nonce in both OR1 and OR2.  This holds because
   4.206 -  OR2 encrypts Nonce NB.  It prevents the attack that can occur in the
   4.207 -  over-simplified version of this protocol: see OtwayRees_Bad.*)
   4.208 -Goal "[| A \\<notin> bad;  evs \\<in> otway |]                      \
   4.209 -\     ==> Crypt (shrK A) {|NA, Agent A, Agent B|} \\<in> parts (knows Spy evs) --> \
   4.210 -\         Crypt (shrK A) {|NA', NA, Agent A', Agent A|}  \
   4.211 -\           \\<notin> parts (knows Spy evs)";
   4.212 -by (parts_induct_tac 1);
   4.213 -by Auto_tac;
   4.214 -qed_spec_mp "no_nonce_OR1_OR2";
   4.215 -
   4.216 -val nonce_OR1_OR2_E = no_nonce_OR1_OR2 RSN (2, rev_notE);
   4.217 -
   4.218 -(*Crucial property: If the encrypted message appears, and A has used NA
   4.219 -  to start a run, then it originated with the Server!*)
   4.220 -Goal "[| A \\<notin> bad;  evs \\<in> otway |]                                  \
   4.221 -\     ==> Says A B {|NA, Agent A, Agent B,                          \
   4.222 -\                    Crypt (shrK A) {|NA, Agent A, Agent B|}|} \\<in> set evs --> \
   4.223 -\         Crypt (shrK A) {|NA, Key K|} \\<in> parts (knows Spy evs)          \
   4.224 -\         --> (\\<exists>NB. Says Server B                                     \
   4.225 -\                        {|NA,                                          \
   4.226 -\                          Crypt (shrK A) {|NA, Key K|},                \
   4.227 -\                          Crypt (shrK B) {|NB, Key K|}|} \\<in> set evs)";
   4.228 -by (parts_induct_tac 1);
   4.229 -by (Blast_tac 1);
   4.230 -(*OR1: it cannot be a new Nonce, contradiction.*)
   4.231 -by (Blast_tac 1);
   4.232 -(*OR4*)
   4.233 -by (blast_tac (claset() addSIs [Crypt_imp_OR1]) 2);
   4.234 -by (asm_simp_tac (simpset() addsimps [ex_disj_distrib]) 1);
   4.235 -by (blast_tac (claset() addSEs  [nonce_OR1_OR2_E] addIs [unique_NA]) 1);
   4.236 -qed_spec_mp "NA_Crypt_imp_Server_msg";
   4.237 -
   4.238 -
   4.239 -(*Corollary: if A receives B's OR4 message and the nonce NA agrees
   4.240 -  then the key really did come from the Server!  CANNOT prove this of the
   4.241 -  bad form of this protocol, even though we can prove
   4.242 -  Spy_not_see_encrypted_key*)
   4.243 -Goal "[| Says A  B {|NA, Agent A, Agent B,                       \
   4.244 -\                Crypt (shrK A) {|NA, Agent A, Agent B|}|} \\<in> set evs; \
   4.245 -\        Gets A {|NA, Crypt (shrK A) {|NA, Key K|}|} \\<in> set evs; \
   4.246 -\    A \\<notin> bad;  evs \\<in> otway |]                              \
   4.247 -\ ==> \\<exists>NB. Says Server B                                  \
   4.248 -\              {|NA,                                        \
   4.249 -\                Crypt (shrK A) {|NA, Key K|},              \
   4.250 -\                Crypt (shrK B) {|NB, Key K|}|}             \
   4.251 -\                \\<in> set evs";
   4.252 -by (blast_tac (claset() addSIs [NA_Crypt_imp_Server_msg]) 1);
   4.253 -qed "A_trusts_OR4";
   4.254 -
   4.255 -
   4.256 -(** Crucial secrecy property: Spy does not see the keys sent in msg OR3
   4.257 -    Does not in itself guarantee security: an attack could violate 
   4.258 -    the premises, e.g. by having A=Spy **)
   4.259 -
   4.260 -Goal "[| A \\<notin> bad;  B \\<notin> bad;  evs \\<in> otway |]                  \
   4.261 -\ ==> Says Server B                                            \
   4.262 -\       {|NA, Crypt (shrK A) {|NA, Key K|},                    \
   4.263 -\         Crypt (shrK B) {|NB, Key K|}|} \\<in> set evs -->         \
   4.264 -\     Notes Spy {|NA, NB, Key K|} \\<notin> set evs -->               \
   4.265 -\     Key K \\<notin> analz (knows Spy evs)";
   4.266 -by (etac otway.induct 1);
   4.267 -by analz_knows_Spy_tac;
   4.268 -by (ALLGOALS
   4.269 -    (asm_simp_tac (simpset() addcongs [conj_cong] 
   4.270 -                             addsimps [analz_insert_eq, analz_insert_freshK]
   4.271 -                                      @ pushes @ split_ifs)));
   4.272 -(*Oops*)
   4.273 -by (blast_tac (claset() addSDs [unique_session_keys]) 4);
   4.274 -(*OR4*) 
   4.275 -by (Blast_tac 3);
   4.276 -(*OR3*)
   4.277 -by (Blast_tac 2);
   4.278 -(*Fake*) 
   4.279 -by (spy_analz_tac 1);
   4.280 -val lemma = result() RS mp RS mp RSN(2,rev_notE);
   4.281 -
   4.282 -Goal "[| Says Server B                                           \
   4.283 -\         {|NA, Crypt (shrK A) {|NA, Key K|},                    \
   4.284 -\               Crypt (shrK B) {|NB, Key K|}|} \\<in> set evs;        \
   4.285 -\        Notes Spy {|NA, NB, Key K|} \\<notin> set evs;                 \
   4.286 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> otway |]                    \
   4.287 -\     ==> Key K \\<notin> analz (knows Spy evs)";
   4.288 -by (blast_tac (claset() addDs [Says_Server_message_form] addSEs [lemma]) 1);
   4.289 -qed "Spy_not_see_encrypted_key";
   4.290 -
   4.291 -
   4.292 -(*A's guarantee.  The Oops premise quantifies over NB because A cannot know
   4.293 -  what it is.*)
   4.294 -Goal "[| Says A  B {|NA, Agent A, Agent B,                       \
   4.295 -\                    Crypt (shrK A) {|NA, Agent A, Agent B|}|} \\<in> set evs; \
   4.296 -\        Gets A {|NA, Crypt (shrK A) {|NA, Key K|}|} \\<in> set evs; \
   4.297 -\        ALL NB. Notes Spy {|NA, NB, Key K|} \\<notin> set evs;         \
   4.298 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> otway |]                    \
   4.299 -\     ==> Key K \\<notin> analz (knows Spy evs)";
   4.300 -by (blast_tac (claset() addSDs [A_trusts_OR4, Spy_not_see_encrypted_key]) 1);
   4.301 -qed "A_gets_good_key";
   4.302 -
   4.303 -
   4.304 -(**** Authenticity properties relating to NB ****)
   4.305 -
   4.306 -(*Only OR2 can have caused such a part of a message to appear.  We do not
   4.307 -  know anything about X: it does NOT have to have the right form.*)
   4.308 -Goal "[| Crypt (shrK B) {|NA, NB, Agent A, Agent B|}       \
   4.309 -\          \\<in> parts (knows Spy evs);  \
   4.310 -\        B \\<notin> bad;  evs \\<in> otway |]                         \
   4.311 -\     ==> \\<exists>X. Says B Server                              \
   4.312 -\                {|NA, Agent A, Agent B, X,                       \
   4.313 -\                  Crypt (shrK B) {|NA, NB, Agent A, Agent B|}|}  \
   4.314 -\                \\<in> set evs";
   4.315 -by (etac rev_mp 1);
   4.316 -by (parts_induct_tac 1);
   4.317 -by (ALLGOALS Blast_tac);
   4.318 -qed "Crypt_imp_OR2";
   4.319 -
   4.320 -
   4.321 -(** The Nonce NB uniquely identifies B's  message. **)
   4.322 -
   4.323 -Goal "[| Crypt (shrK B) {|NA, NB, Agent A, Agent B|} \\<in> parts(knows Spy evs); \
   4.324 -\        Crypt (shrK B) {|NC, NB, Agent C, Agent B|} \\<in> parts(knows Spy evs); \
   4.325 -\          evs \\<in> otway;  B \\<notin> bad |]             \
   4.326 -\        ==> NC = NA & C = A";
   4.327 -by (etac rev_mp 1);
   4.328 -by (etac rev_mp 1);
   4.329 -by (parts_induct_tac 1);
   4.330 -(*Fake, OR2*)
   4.331 -by (REPEAT (Blast_tac 1)); 
   4.332 -qed "unique_NB";
   4.333 -
   4.334 -(*If the encrypted message appears, and B has used Nonce NB,
   4.335 -  then it originated with the Server!  Quite messy proof.*)
   4.336 -Goal "[| B \\<notin> bad;  evs \\<in> otway |]                                    \
   4.337 -\ ==> Crypt (shrK B) {|NB, Key K|} \\<in> parts (knows Spy evs)            \
   4.338 -\     --> (ALL X'. Says B Server                                      \
   4.339 -\                    {|NA, Agent A, Agent B, X',                      \
   4.340 -\                      Crypt (shrK B) {|NA, NB, Agent A, Agent B|}|}  \
   4.341 -\          \\<in> set evs                                                  \
   4.342 -\          --> Says Server B                                          \
   4.343 -\               {|NA, Crypt (shrK A) {|NA, Key K|},                   \
   4.344 -\                     Crypt (shrK B) {|NB, Key K|}|}                  \
   4.345 -\                   \\<in> set evs)";
   4.346 -by (asm_full_simp_tac (simpset() addsimps []) 1); 
   4.347 -by (parts_induct_tac 1);
   4.348 -by (Blast_tac 1);
   4.349 -(*OR1: it cannot be a new Nonce, contradiction.*)
   4.350 -by (Blast_tac 1);
   4.351 -(*OR4*)
   4.352 -by (blast_tac (claset() addSDs [Crypt_imp_OR2]) 2);
   4.353 -(*OR3: needs AddSEs [MPair_parts] or it takes forever!*)
   4.354 -by (blast_tac (claset() addDs [unique_NB]
   4.355 -			addEs [nonce_OR1_OR2_E]) 1);
   4.356 -qed_spec_mp "NB_Crypt_imp_Server_msg";
   4.357 -
   4.358 -
   4.359 -(*Guarantee for B: if it gets a message with matching NB then the Server
   4.360 -  has sent the correct message.*)
   4.361 -Goal "[| Says B Server {|NA, Agent A, Agent B, X',              \
   4.362 -\                        Crypt (shrK B) {|NA, NB, Agent A, Agent B|} |} \
   4.363 -\          \\<in> set evs;                                           \
   4.364 -\        Gets B {|NA, X, Crypt (shrK B) {|NB, Key K|}|} \\<in> set evs;   \
   4.365 -\        B \\<notin> bad;  evs \\<in> otway |]                              \
   4.366 -\     ==> Says Server B                                         \
   4.367 -\              {|NA,                                            \
   4.368 -\                Crypt (shrK A) {|NA, Key K|},                  \
   4.369 -\                Crypt (shrK B) {|NB, Key K|}|}                 \
   4.370 -\                \\<in> set evs";
   4.371 -by (blast_tac (claset() addSIs [NB_Crypt_imp_Server_msg]) 1);
   4.372 -qed "B_trusts_OR3";
   4.373 -
   4.374 -
   4.375 -(*The obvious combination of B_trusts_OR3 with Spy_not_see_encrypted_key*)
   4.376 -Goal "[| Says B Server {|NA, Agent A, Agent B, X',              \
   4.377 -\                        Crypt (shrK B) {|NA, NB, Agent A, Agent B|} |} \
   4.378 -\          \\<in> set evs;                                           \
   4.379 -\        Gets B {|NA, X, Crypt (shrK B) {|NB, Key K|}|} \\<in> set evs;   \
   4.380 -\        Notes Spy {|NA, NB, Key K|} \\<notin> set evs;                \
   4.381 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> otway |]                   \
   4.382 -\     ==> Key K \\<notin> analz (knows Spy evs)";
   4.383 -by (blast_tac (claset() addSDs [B_trusts_OR3, Spy_not_see_encrypted_key]) 1);
   4.384 -qed "B_gets_good_key";
   4.385 -
   4.386 -
   4.387 -Goal "[| Says Server B                                       \
   4.388 -\           {|NA, Crypt (shrK A) {|NA, Key K|},              \
   4.389 -\             Crypt (shrK B) {|NB, Key K|}|} \\<in> set evs;      \
   4.390 -\        B \\<notin> bad;  evs \\<in> otway |]                           \
   4.391 -\ ==> \\<exists>X. Says B Server {|NA, Agent A, Agent B, X,         \
   4.392 -\                           Crypt (shrK B) {|NA, NB, Agent A, Agent B|} |} \
   4.393 -\             \\<in> set evs";
   4.394 -by (etac rev_mp 1);
   4.395 -by (etac otway.induct 1);
   4.396 -by (ALLGOALS Asm_simp_tac);
   4.397 -by (blast_tac (claset() addSDs [Crypt_imp_OR2]) 3);
   4.398 -by (ALLGOALS Blast_tac);
   4.399 -qed "OR3_imp_OR2";
   4.400 -
   4.401 -
   4.402 -(*After getting and checking OR4, agent A can trust that B has been active.
   4.403 -  We could probably prove that X has the expected form, but that is not
   4.404 -  strictly necessary for authentication.*)
   4.405 -Goal "[| Gets A {|NA, Crypt (shrK A) {|NA, Key K|}|} \\<in> set evs;        \
   4.406 -\        Says A  B {|NA, Agent A, Agent B,                                \
   4.407 -\                    Crypt (shrK A) {|NA, Agent A, Agent B|}|} \\<in> set evs; \
   4.408 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> otway |]                             \
   4.409 -\ ==> \\<exists>NB X. Says B Server {|NA, Agent A, Agent B, X,               \
   4.410 -\                              Crypt (shrK B)  {|NA, NB, Agent A, Agent B|} |}\
   4.411 -\                \\<in> set evs";
   4.412 -by (blast_tac (claset() delrules [Gets_imp_knows_Spy RS parts.Inj]
   4.413 -			addSDs [A_trusts_OR4, OR3_imp_OR2]) 1);
   4.414 -qed "A_auths_B";
     5.1 --- a/src/HOL/Auth/OtwayRees.thy	Wed Apr 11 11:53:54 2001 +0200
     5.2 +++ b/src/HOL/Auth/OtwayRees.thy	Thu Apr 12 12:45:05 2001 +0200
     5.3 @@ -1,44 +1,49 @@
     5.4 -(*  
     5.5 +(*  Title:      HOL/Auth/OtwayRees
     5.6 +    ID:         $Id$
     5.7 +    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     5.8 +    Copyright   1996  University of Cambridge
     5.9 +
    5.10  Inductive relation "otway" for the Otway-Rees protocol
    5.11  extended by Gets primitive.
    5.12  
    5.13  Version that encrypts Nonce NB
    5.14  
    5.15 +From page 244 of
    5.16 +  Burrows, Abadi and Needham.  A Logic of Authentication.
    5.17 +  Proc. Royal Soc. 426 (1989)
    5.18  *)
    5.19  
    5.20 -OtwayRees = Shared + 
    5.21 +theory OtwayRees = Shared:
    5.22  
    5.23  
    5.24 -consts  otway   :: event list set
    5.25 +consts  otway   :: "event list set"
    5.26  inductive "otway"
    5.27 -  intrs 
    5.28 +  intros
    5.29           (*Initial trace is empty*)
    5.30 -    Nil  "[] \\<in> otway"
    5.31 -
    5.32 -         (** These rules allow agents to send messages to themselves **)
    5.33 +   Nil:  "[] \<in> otway"
    5.34  
    5.35           (*The spy MAY say anything he CAN say.  We do not expect him to
    5.36             invent new nonces here, but he can also use NS1.  Common to
    5.37             all similar protocols.*)
    5.38 -    Fake "[| evsf \\<in> otway;  X \\<in> synth (analz (knows Spy evsf)) |]
    5.39 -          ==> Says Spy B X  # evsf : otway"
    5.40 +   Fake: "[| evsf \<in> otway;  X \<in> synth (analz (knows Spy evsf)) |]
    5.41 +          ==> Says Spy B X  # evsf \<in> otway"
    5.42  
    5.43           (*A message that has been sent can be received by the
    5.44             intended recipient.*)
    5.45 -    Reception "[| evsr \\<in> otway;  Says A B X : set evsr |]
    5.46 -               ==> Gets B X # evsr : otway"
    5.47 +   Reception: "[| evsr \<in> otway;  Says A B X \<in>set evsr |]
    5.48 +               ==> Gets B X # evsr \<in> otway"
    5.49  
    5.50           (*Alice initiates a protocol run*)
    5.51 -    OR1  "[| evs1 \\<in> otway;  Nonce NA \\<notin> used evs1 |]
    5.52 -          ==> Says A B {|Nonce NA, Agent A, Agent B, 
    5.53 -                         Crypt (shrK A) {|Nonce NA, Agent A, Agent B|} |} 
    5.54 +   OR1:  "[| evs1 \<in> otway;  Nonce NA \<notin> used evs1 |]
    5.55 +          ==> Says A B {|Nonce NA, Agent A, Agent B,
    5.56 +                         Crypt (shrK A) {|Nonce NA, Agent A, Agent B|} |}
    5.57                   # evs1 : otway"
    5.58  
    5.59           (*Bob's response to Alice's message.  Note that NB is encrypted.*)
    5.60 -    OR2  "[| evs2 \\<in> otway;  Nonce NB \\<notin> used evs2;
    5.61 +   OR2:  "[| evs2 \<in> otway;  Nonce NB \<notin> used evs2;
    5.62               Gets B {|Nonce NA, Agent A, Agent B, X|} : set evs2 |]
    5.63 -          ==> Says B Server 
    5.64 -                  {|Nonce NA, Agent A, Agent B, X, 
    5.65 +          ==> Says B Server
    5.66 +                  {|Nonce NA, Agent A, Agent B, X,
    5.67                      Crypt (shrK B)
    5.68                        {|Nonce NA, Nonce NB, Agent A, Agent B|}|}
    5.69                   # evs2 : otway"
    5.70 @@ -46,23 +51,23 @@
    5.71           (*The Server receives Bob's message and checks that the three NAs
    5.72             match.  Then he sends a new session key to Bob with a packet for
    5.73             forwarding to Alice.*)
    5.74 -    OR3  "[| evs3 \\<in> otway;  Key KAB \\<notin> used evs3;
    5.75 -             Gets Server 
    5.76 -                  {|Nonce NA, Agent A, Agent B, 
    5.77 -                    Crypt (shrK A) {|Nonce NA, Agent A, Agent B|}, 
    5.78 +   OR3:  "[| evs3 \<in> otway;  Key KAB \<notin> used evs3;
    5.79 +             Gets Server
    5.80 +                  {|Nonce NA, Agent A, Agent B,
    5.81 +                    Crypt (shrK A) {|Nonce NA, Agent A, Agent B|},
    5.82                      Crypt (shrK B) {|Nonce NA, Nonce NB, Agent A, Agent B|}|}
    5.83                 : set evs3 |]
    5.84 -          ==> Says Server B 
    5.85 -                  {|Nonce NA, 
    5.86 +          ==> Says Server B
    5.87 +                  {|Nonce NA,
    5.88                      Crypt (shrK A) {|Nonce NA, Key KAB|},
    5.89                      Crypt (shrK B) {|Nonce NB, Key KAB|}|}
    5.90                   # evs3 : otway"
    5.91  
    5.92           (*Bob receives the Server's (?) message and compares the Nonces with
    5.93  	   those in the message he previously sent the Server.
    5.94 -           Need B \\<noteq> Server because we allow messages to self.*)
    5.95 -    OR4  "[| evs4 \\<in> otway;  B \\<noteq> Server;
    5.96 -             Says B Server {|Nonce NA, Agent A, Agent B, X', 
    5.97 +           Need B \<noteq> Server because we allow messages to self.*)
    5.98 +   OR4:  "[| evs4 \<in> otway;  B \<noteq> Server;
    5.99 +             Says B Server {|Nonce NA, Agent A, Agent B, X',
   5.100                               Crypt (shrK B)
   5.101                                     {|Nonce NA, Nonce NB, Agent A, Agent B|}|}
   5.102                 : set evs4;
   5.103 @@ -72,9 +77,391 @@
   5.104  
   5.105           (*This message models possible leaks of session keys.  The nonces
   5.106             identify the protocol run.*)
   5.107 -    Oops "[| evso \\<in> otway;  
   5.108 +   Oops: "[| evso \<in> otway;
   5.109               Says Server B {|Nonce NA, X, Crypt (shrK B) {|Nonce NB, Key K|}|}
   5.110                 : set evso |]
   5.111            ==> Notes Spy {|Nonce NA, Nonce NB, Key K|} # evso : otway"
   5.112  
   5.113 +
   5.114 +declare Says_imp_knows_Spy [THEN analz.Inj, dest]
   5.115 +declare parts.Body  [dest]
   5.116 +declare analz_into_parts [dest]
   5.117 +declare Fake_parts_insert_in_Un  [dest]
   5.118 +
   5.119 +
   5.120 +(*A "possibility property": there are traces that reach the end*)
   5.121 +lemma "B \<noteq> Server
   5.122 +      ==> \<exists>K. \<exists>evs \<in> otway.
   5.123 +             Says B A {|Nonce NA, Crypt (shrK A) {|Nonce NA, Key K|}|}
   5.124 +               \<in> set evs"
   5.125 +apply (intro exI bexI)
   5.126 +apply (rule_tac [2] otway.Nil
   5.127 +                    [THEN otway.OR1, THEN otway.Reception,
   5.128 +                     THEN otway.OR2, THEN otway.Reception,
   5.129 +                     THEN otway.OR3, THEN otway.Reception, THEN otway.OR4])
   5.130 +apply possibility
   5.131 +done
   5.132 +
   5.133 +lemma Gets_imp_Says [dest!]:
   5.134 +     "[| Gets B X \<in> set evs; evs \<in> otway |] ==> \<exists>A. Says A B X \<in> set evs"
   5.135 +apply (erule rev_mp)
   5.136 +apply (erule otway.induct)
   5.137 +apply auto
   5.138 +done
   5.139 +
   5.140 +
   5.141 +(**** Inductive proofs about otway ****)
   5.142 +
   5.143 +(** For reasoning about the encrypted portion of messages **)
   5.144 +
   5.145 +lemma OR2_analz_knows_Spy:
   5.146 +     "[| Gets B {|N, Agent A, Agent B, X|} \<in> set evs;  evs \<in> otway |]
   5.147 +      ==> X \<in> analz (knows Spy evs)"
   5.148 +by blast
   5.149 +
   5.150 +lemma OR4_analz_knows_Spy:
   5.151 +     "[| Gets B {|N, X, Crypt (shrK B) X'|} \<in> set evs;  evs \<in> otway |]
   5.152 +      ==> X \<in> analz (knows Spy evs)"
   5.153 +by blast
   5.154 +
   5.155 +(*These lemmas assist simplification by removing forwarded X-variables.
   5.156 +  We can replace them by rewriting with parts_insert2 and proving using
   5.157 +  dest: parts_cut, but the proofs become more difficult.*)
   5.158 +lemmas OR2_parts_knows_Spy =
   5.159 +    OR2_analz_knows_Spy [THEN analz_into_parts, standard]
   5.160 +
   5.161 +(*There could be OR4_parts_knows_Spy and Oops_parts_knows_Spy, but for
   5.162 +  some reason proofs work without them!*)
   5.163 +
   5.164 +
   5.165 +(** Theorems of the form X \<notin> parts (knows Spy evs) imply that NOBODY
   5.166 +    sends messages containing X! **)
   5.167 +
   5.168 +(*Spy never sees a good agent's shared key!*)
   5.169 +lemma Spy_see_shrK [simp]:
   5.170 +     "evs \<in> otway ==> (Key (shrK A) \<in> parts (knows Spy evs)) = (A \<in> bad)"
   5.171 +apply (erule otway.induct, force,
   5.172 +       drule_tac [4] OR2_parts_knows_Spy, simp_all)
   5.173 +apply blast+
   5.174 +done
   5.175 +
   5.176 +lemma Spy_analz_shrK [simp]:
   5.177 +     "evs \<in> otway ==> (Key (shrK A) \<in> analz (knows Spy evs)) = (A \<in> bad)"
   5.178 +by auto
   5.179 +
   5.180 +lemma Spy_see_shrK_D [dest!]:
   5.181 +     "[|Key (shrK A) \<in> parts (knows Spy evs);  evs \<in> otway|] ==> A \<in> bad"
   5.182 +by (blast dest: Spy_see_shrK)
   5.183 +
   5.184 +
   5.185 +(*** Proofs involving analz ***)
   5.186 +
   5.187 +(*Describes the form of K and NA when the Server sends this message.  Also
   5.188 +  for Oops case.*)
   5.189 +lemma Says_Server_message_form:
   5.190 +     "[| Says Server B {|NA, X, Crypt (shrK B) {|NB, Key K|}|} \<in> set evs;
   5.191 +         evs \<in> otway |]
   5.192 +      ==> K \<notin> range shrK & (\<exists>i. NA = Nonce i) & (\<exists>j. NB = Nonce j)"
   5.193 +apply (erule rev_mp, erule otway.induct, simp_all)
   5.194 +apply blast
   5.195 +done
   5.196 +
   5.197 +
   5.198 +(****
   5.199 + The following is to prove theorems of the form
   5.200 +
   5.201 +  Key K \<in> analz (insert (Key KAB) (knows Spy evs)) ==>
   5.202 +  Key K \<in> analz (knows Spy evs)
   5.203 +
   5.204 + A more general formula must be proved inductively.
   5.205 +****)
   5.206 +
   5.207 +
   5.208 +(** Session keys are not used to encrypt other session keys **)
   5.209 +
   5.210 +(*The equality makes the induction hypothesis easier to apply*)
   5.211 +lemma analz_image_freshK [rule_format]:
   5.212 + "evs \<in> otway ==>
   5.213 +   \<forall>K KK. KK <= -(range shrK) -->
   5.214 +          (Key K \<in> analz (Key`KK Un (knows Spy evs))) =
   5.215 +          (K \<in> KK | Key K \<in> analz (knows Spy evs))"
   5.216 +apply (erule otway.induct, force)
   5.217 +apply (frule_tac [7] Says_Server_message_form)
   5.218 +apply (drule_tac [6] OR4_analz_knows_Spy)
   5.219 +apply (drule_tac [4] OR2_analz_knows_Spy)
   5.220 +apply analz_freshK
   5.221 +apply spy_analz
   5.222 +done
   5.223 +
   5.224 +
   5.225 +lemma analz_insert_freshK:
   5.226 +  "[| evs \<in> otway;  KAB \<notin> range shrK |] ==>
   5.227 +      Key K \<in> analz (insert (Key KAB) (knows Spy evs)) =
   5.228 +      (K = KAB | Key K \<in> analz (knows Spy evs))"
   5.229 +by (simp only: analz_image_freshK analz_image_freshK_simps)
   5.230 +
   5.231 +
   5.232 +(*** The Key K uniquely identifies the Server's  message. **)
   5.233 +
   5.234 +lemma unique_session_keys:
   5.235 +     "[| Says Server B {|NA, X, Crypt (shrK B) {|NB, K|}|}   \<in> set evs;
   5.236 +         Says Server B' {|NA',X',Crypt (shrK B') {|NB',K|}|} \<in> set evs;
   5.237 +         evs \<in> otway |] ==> X=X' & B=B' & NA=NA' & NB=NB'"
   5.238 +apply (erule rev_mp)
   5.239 +apply (erule rev_mp)
   5.240 +apply (erule otway.induct, simp_all)
   5.241 +(*Remaining cases: OR3 and OR4*)
   5.242 +apply blast+
   5.243 +done
   5.244 +
   5.245 +
   5.246 +(**** Authenticity properties relating to NA ****)
   5.247 +
   5.248 +(*Only OR1 can have caused such a part of a message to appear.*)
   5.249 +lemma Crypt_imp_OR1 [rule_format]:
   5.250 + "[| A \<notin> bad;  evs \<in> otway |]
   5.251 +  ==> Crypt (shrK A) {|NA, Agent A, Agent B|} \<in> parts (knows Spy evs) -->
   5.252 +      Says A B {|NA, Agent A, Agent B,
   5.253 +                 Crypt (shrK A) {|NA, Agent A, Agent B|}|}
   5.254 +        \<in> set evs"
   5.255 +apply (erule otway.induct, force,
   5.256 +       drule_tac [4] OR2_parts_knows_Spy, simp_all)
   5.257 +apply blast+
   5.258 +done
   5.259 +
   5.260 +lemma Crypt_imp_OR1_Gets:
   5.261 +     "[| Gets B {|NA, Agent A, Agent B,
   5.262 +                  Crypt (shrK A) {|NA, Agent A, Agent B|}|} \<in> set evs;
   5.263 +         A \<notin> bad; evs \<in> otway |]
   5.264 +       ==> Says A B {|NA, Agent A, Agent B,
   5.265 +                      Crypt (shrK A) {|NA, Agent A, Agent B|}|}
   5.266 +             \<in> set evs"
   5.267 +by (blast dest: Crypt_imp_OR1)
   5.268 +
   5.269 +
   5.270 +(** The Nonce NA uniquely identifies A's message. **)
   5.271 +
   5.272 +lemma unique_NA:
   5.273 +     "[| Crypt (shrK A) {|NA, Agent A, Agent B|} \<in> parts (knows Spy evs);
   5.274 +         Crypt (shrK A) {|NA, Agent A, Agent C|} \<in> parts (knows Spy evs);
   5.275 +         evs \<in> otway;  A \<notin> bad |]
   5.276 +      ==> B = C"
   5.277 +apply (erule rev_mp, erule rev_mp)
   5.278 +apply (erule otway.induct, force,
   5.279 +       drule_tac [4] OR2_parts_knows_Spy, simp_all)
   5.280 +apply blast+
   5.281 +done
   5.282 +
   5.283 +
   5.284 +(*It is impossible to re-use a nonce in both OR1 and OR2.  This holds because
   5.285 +  OR2 encrypts Nonce NB.  It prevents the attack that can occur in the
   5.286 +  over-simplified version of this protocol: see OtwayRees_Bad.*)
   5.287 +lemma no_nonce_OR1_OR2:
   5.288 +   "[| Crypt (shrK A) {|NA, Agent A, Agent B|} \<in> parts (knows Spy evs);
   5.289 +       A \<notin> bad;  evs \<in> otway |]
   5.290 +    ==> Crypt (shrK A) {|NA', NA, Agent A', Agent A|} \<notin> parts (knows Spy evs)"
   5.291 +apply (erule rev_mp)
   5.292 +apply (erule otway.induct, force,
   5.293 +       drule_tac [4] OR2_parts_knows_Spy, simp_all)
   5.294 +apply blast+
   5.295 +done
   5.296 +
   5.297 +(*Crucial property: If the encrypted message appears, and A has used NA
   5.298 +  to start a run, then it originated with the Server!*)
   5.299 +lemma NA_Crypt_imp_Server_msg [rule_format]:
   5.300 +     "[| A \<notin> bad;  evs \<in> otway |]
   5.301 +      ==> Says A B {|NA, Agent A, Agent B,
   5.302 +                     Crypt (shrK A) {|NA, Agent A, Agent B|}|} \<in> set evs -->
   5.303 +          Crypt (shrK A) {|NA, Key K|} \<in> parts (knows Spy evs)
   5.304 +          --> (\<exists>NB. Says Server B
   5.305 +                         {|NA,
   5.306 +                           Crypt (shrK A) {|NA, Key K|},
   5.307 +                           Crypt (shrK B) {|NB, Key K|}|} \<in> set evs)"
   5.308 +apply (erule otway.induct, force,
   5.309 +       drule_tac [4] OR2_parts_knows_Spy, simp_all)
   5.310 +apply blast
   5.311 +(*OR1: it cannot be a new Nonce, contradiction.*)
   5.312 +apply blast
   5.313 +(*OR3*)
   5.314 +apply (blast dest!: no_nonce_OR1_OR2 intro: unique_NA)
   5.315 +(*OR4*)
   5.316 +apply (blast intro!: Crypt_imp_OR1)
   5.317 +done
   5.318 +
   5.319 +
   5.320 +(*Corollary: if A receives B's OR4 message and the nonce NA agrees
   5.321 +  then the key really did come from the Server!  CANNOT prove this of the
   5.322 +  bad form of this protocol, even though we can prove
   5.323 +  Spy_not_see_encrypted_key*)
   5.324 +lemma A_trusts_OR4:
   5.325 +     "[| Says A  B {|NA, Agent A, Agent B,
   5.326 +                     Crypt (shrK A) {|NA, Agent A, Agent B|}|} \<in> set evs;
   5.327 +         Says B' A {|NA, Crypt (shrK A) {|NA, Key K|}|} \<in> set evs;
   5.328 +     A \<notin> bad;  evs \<in> otway |]
   5.329 +  ==> \<exists>NB. Says Server B
   5.330 +               {|NA,
   5.331 +                 Crypt (shrK A) {|NA, Key K|},
   5.332 +                 Crypt (shrK B) {|NB, Key K|}|}
   5.333 +                 \<in> set evs"
   5.334 +by (blast intro!: NA_Crypt_imp_Server_msg)
   5.335 +
   5.336 +
   5.337 +(** Crucial secrecy property: Spy does not see the keys sent in msg OR3
   5.338 +    Does not in itself guarantee security: an attack could violate
   5.339 +    the premises, e.g. by having A=Spy **)
   5.340 +
   5.341 +lemma secrecy_lemma:
   5.342 + "[| A \<notin> bad;  B \<notin> bad;  evs \<in> otway |]
   5.343 +  ==> Says Server B
   5.344 +        {|NA, Crypt (shrK A) {|NA, Key K|},
   5.345 +          Crypt (shrK B) {|NB, Key K|}|} \<in> set evs -->
   5.346 +      Notes Spy {|NA, NB, Key K|} \<notin> set evs -->
   5.347 +      Key K \<notin> analz (knows Spy evs)"
   5.348 +apply (erule otway.induct, force)
   5.349 +apply (frule_tac [7] Says_Server_message_form)
   5.350 +apply (drule_tac [6] OR4_analz_knows_Spy)
   5.351 +apply (drule_tac [4] OR2_analz_knows_Spy)
   5.352 +apply (simp_all add: analz_insert_eq analz_insert_freshK pushes)
   5.353 +apply spy_analz  (*Fake*)
   5.354 +(*OR3, OR4, Oops*)
   5.355 +apply (blast dest: unique_session_keys)+
   5.356 +done
   5.357 +
   5.358 +lemma Spy_not_see_encrypted_key:
   5.359 +     "[| Says Server B
   5.360 +          {|NA, Crypt (shrK A) {|NA, Key K|},
   5.361 +                Crypt (shrK B) {|NB, Key K|}|} \<in> set evs;
   5.362 +         Notes Spy {|NA, NB, Key K|} \<notin> set evs;
   5.363 +         A \<notin> bad;  B \<notin> bad;  evs \<in> otway |]
   5.364 +      ==> Key K \<notin> analz (knows Spy evs)"
   5.365 +by (blast dest: Says_Server_message_form secrecy_lemma)
   5.366 +
   5.367 +
   5.368 +(*A's guarantee.  The Oops premise quantifies over NB because A cannot know
   5.369 +  what it is.*)
   5.370 +lemma A_gets_good_key:
   5.371 +     "[| Says A  B {|NA, Agent A, Agent B,
   5.372 +                     Crypt (shrK A) {|NA, Agent A, Agent B|}|} \<in> set evs;
   5.373 +         Says B' A {|NA, Crypt (shrK A) {|NA, Key K|}|} \<in> set evs;
   5.374 +         \<forall>NB. Notes Spy {|NA, NB, Key K|} \<notin> set evs;
   5.375 +         A \<notin> bad;  B \<notin> bad;  evs \<in> otway |]
   5.376 +      ==> Key K \<notin> analz (knows Spy evs)"
   5.377 +by (blast dest!: A_trusts_OR4 Spy_not_see_encrypted_key)
   5.378 +
   5.379 +
   5.380 +
   5.381 +(**** Authenticity properties relating to NB ****)
   5.382 +
   5.383 +(*Only OR2 can have caused such a part of a message to appear.  We do not
   5.384 +  know anything about X: it does NOT have to have the right form.*)
   5.385 +lemma Crypt_imp_OR2:
   5.386 +     "[| Crypt (shrK B) {|NA, NB, Agent A, Agent B|} \<in> parts (knows Spy evs);
   5.387 +         B \<notin> bad;  evs \<in> otway |]
   5.388 +      ==> \<exists>X. Says B Server
   5.389 +                 {|NA, Agent A, Agent B, X,
   5.390 +                   Crypt (shrK B) {|NA, NB, Agent A, Agent B|}|}
   5.391 +                 \<in> set evs"
   5.392 +apply (erule rev_mp)
   5.393 +apply (erule otway.induct, force,
   5.394 +       drule_tac [4] OR2_parts_knows_Spy, simp_all)
   5.395 +apply blast+
   5.396 +done
   5.397 +
   5.398 +
   5.399 +(** The Nonce NB uniquely identifies B's  message. **)
   5.400 +
   5.401 +lemma unique_NB:
   5.402 +     "[| Crypt (shrK B) {|NA, NB, Agent A, Agent B|} \<in> parts(knows Spy evs);
   5.403 +         Crypt (shrK B) {|NC, NB, Agent C, Agent B|} \<in> parts(knows Spy evs);
   5.404 +           evs \<in> otway;  B \<notin> bad |]
   5.405 +         ==> NC = NA & C = A"
   5.406 +apply (erule rev_mp, erule rev_mp)
   5.407 +apply (erule otway.induct, force,
   5.408 +       drule_tac [4] OR2_parts_knows_Spy, simp_all)
   5.409 +(*Fake, OR2*)
   5.410 +apply blast+
   5.411 +done
   5.412 +
   5.413 +(*If the encrypted message appears, and B has used Nonce NB,
   5.414 +  then it originated with the Server!  Quite messy proof.*)
   5.415 +lemma NB_Crypt_imp_Server_msg [rule_format]:
   5.416 + "[| B \<notin> bad;  evs \<in> otway |]
   5.417 +  ==> Crypt (shrK B) {|NB, Key K|} \<in> parts (knows Spy evs)
   5.418 +      --> (\<forall>X'. Says B Server
   5.419 +                     {|NA, Agent A, Agent B, X',
   5.420 +                       Crypt (shrK B) {|NA, NB, Agent A, Agent B|}|}
   5.421 +           \<in> set evs
   5.422 +           --> Says Server B
   5.423 +                {|NA, Crypt (shrK A) {|NA, Key K|},
   5.424 +                      Crypt (shrK B) {|NB, Key K|}|}
   5.425 +                    \<in> set evs)"
   5.426 +apply simp
   5.427 +apply (erule otway.induct, force,
   5.428 +       drule_tac [4] OR2_parts_knows_Spy, simp_all)
   5.429 +apply blast
   5.430 +(*OR1: it cannot be a new Nonce, contradiction.*)
   5.431 +(*OR2*)
   5.432 +apply blast
   5.433 +(*OR3: needs elim: MPair_parts or it takes forever!*)
   5.434 +apply (blast dest: unique_NB dest!: no_nonce_OR1_OR2)
   5.435 +(*OR4*)
   5.436 +apply (blast dest!: Crypt_imp_OR2)
   5.437 +done
   5.438 +
   5.439 +
   5.440 +(*Guarantee for B: if it gets a message with matching NB then the Server
   5.441 +  has sent the correct message.*)
   5.442 +lemma B_trusts_OR3:
   5.443 +     "[| Says B Server {|NA, Agent A, Agent B, X',
   5.444 +                         Crypt (shrK B) {|NA, NB, Agent A, Agent B|} |}
   5.445 +           \<in> set evs;
   5.446 +         Gets B {|NA, X, Crypt (shrK B) {|NB, Key K|}|} \<in> set evs;
   5.447 +         B \<notin> bad;  evs \<in> otway |]
   5.448 +      ==> Says Server B
   5.449 +               {|NA,
   5.450 +                 Crypt (shrK A) {|NA, Key K|},
   5.451 +                 Crypt (shrK B) {|NB, Key K|}|}
   5.452 +                 \<in> set evs"
   5.453 +by (blast intro!: NB_Crypt_imp_Server_msg)
   5.454 +
   5.455 +
   5.456 +(*The obvious combination of B_trusts_OR3 with Spy_not_see_encrypted_key*)
   5.457 +lemma B_gets_good_key:
   5.458 +     "[| Says B Server {|NA, Agent A, Agent B, X',
   5.459 +                         Crypt (shrK B) {|NA, NB, Agent A, Agent B|} |}
   5.460 +           \<in> set evs;
   5.461 +         Gets B {|NA, X, Crypt (shrK B) {|NB, Key K|}|} \<in> set evs;
   5.462 +         Notes Spy {|NA, NB, Key K|} \<notin> set evs;
   5.463 +         A \<notin> bad;  B \<notin> bad;  evs \<in> otway |]
   5.464 +      ==> Key K \<notin> analz (knows Spy evs)"
   5.465 +by (blast dest!: B_trusts_OR3 Spy_not_see_encrypted_key)
   5.466 +
   5.467 +
   5.468 +lemma OR3_imp_OR2:
   5.469 +     "[| Says Server B
   5.470 +              {|NA, Crypt (shrK A) {|NA, Key K|},
   5.471 +                Crypt (shrK B) {|NB, Key K|}|} \<in> set evs;
   5.472 +         B \<notin> bad;  evs \<in> otway |]
   5.473 +  ==> \<exists>X. Says B Server {|NA, Agent A, Agent B, X,
   5.474 +                            Crypt (shrK B) {|NA, NB, Agent A, Agent B|} |}
   5.475 +              \<in> set evs"
   5.476 +apply (erule rev_mp)
   5.477 +apply (erule otway.induct, simp_all)
   5.478 +apply (blast dest!: Crypt_imp_OR2)+
   5.479 +done
   5.480 +
   5.481 +
   5.482 +(*After getting and checking OR4, agent A can trust that B has been active.
   5.483 +  We could probably prove that X has the expected form, but that is not
   5.484 +  strictly necessary for authentication.*)
   5.485 +lemma A_auths_B:
   5.486 +     "[| Says B' A {|NA, Crypt (shrK A) {|NA, Key K|}|} \<in> set evs;
   5.487 +         Says A  B {|NA, Agent A, Agent B,
   5.488 +                     Crypt (shrK A) {|NA, Agent A, Agent B|}|} \<in> set evs;
   5.489 +         A \<notin> bad;  B \<notin> bad;  evs \<in> otway |]
   5.490 +  ==> \<exists>NB X. Says B Server {|NA, Agent A, Agent B, X,
   5.491 +                               Crypt (shrK B)  {|NA, NB, Agent A, Agent B|} |}
   5.492 +                 \<in> set evs"
   5.493 +by (blast dest!: A_trusts_OR4 OR3_imp_OR2)
   5.494 +
   5.495  end
     6.1 --- a/src/HOL/Auth/OtwayRees_AN.ML	Wed Apr 11 11:53:54 2001 +0200
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,285 +0,0 @@
     6.4 -(*  Title:      HOL/Auth/OtwayRees_AN
     6.5 -    ID:         $Id$
     6.6 -    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     6.7 -    Copyright   1996  University of Cambridge
     6.8 -
     6.9 -Inductive relation "otway" for the Otway-Rees protocol.
    6.10 -
    6.11 -Abadi-Needham version: minimal encryption, explicit messages
    6.12 -
    6.13 -From page 11 of
    6.14 -  Abadi and Needham.  Prudent Engineering Practice for Cryptographic Protocols.
    6.15 -  IEEE Trans. SE 22 (1), 1996
    6.16 -*)
    6.17 -
    6.18 -AddDs  [Says_imp_knows_Spy RS parts.Inj, parts.Body];
    6.19 -AddDs  [impOfSubs analz_subset_parts, impOfSubs Fake_parts_insert];
    6.20 -
    6.21 -
    6.22 -(*A "possibility property": there are traces that reach the end*)
    6.23 -Goal "B \\<noteq> Server   \
    6.24 -\     ==> \\<exists>K. \\<exists>evs \\<in> otway.                                      \
    6.25 -\          Says B A (Crypt (shrK A) {|Nonce NA, Agent A, Agent B, Key K|}) \
    6.26 -\            \\<in> set evs";
    6.27 -by (REPEAT (resolve_tac [exI,bexI] 1));
    6.28 -by (rtac (otway.Nil RS 
    6.29 -          otway.OR1 RS otway.Reception RS
    6.30 -          otway.OR2 RS otway.Reception RS 
    6.31 -          otway.OR3 RS otway.Reception RS otway.OR4) 2);
    6.32 -by possibility_tac;
    6.33 -result();
    6.34 -
    6.35 -Goal "[| Gets B X \\<in> set evs; evs \\<in> otway |] ==> \\<exists>A. Says A B X \\<in> set evs";
    6.36 -by (etac rev_mp 1);
    6.37 -by (etac otway.induct 1);
    6.38 -by Auto_tac;
    6.39 -qed"Gets_imp_Says";
    6.40 -
    6.41 -(*Must be proved separately for each protocol*)
    6.42 -Goal "[| Gets B X \\<in> set evs; evs \\<in> otway |]  ==> X \\<in> knows Spy evs";
    6.43 -by (blast_tac (claset() addSDs [Gets_imp_Says, Says_imp_knows_Spy]) 1);
    6.44 -qed"Gets_imp_knows_Spy";
    6.45 -AddDs [Gets_imp_knows_Spy RS parts.Inj];
    6.46 -
    6.47 -
    6.48 -(**** Inductive proofs about otway ****)
    6.49 -
    6.50 -(** For reasoning about the encrypted portion of messages **)
    6.51 -
    6.52 -Goal "[| Gets B {|X, Crypt(shrK B) X'|} \\<in> set evs;  evs \\<in> otway |]  \
    6.53 -\     ==> X \\<in> analz (knows Spy evs)";
    6.54 -by (blast_tac (claset() addSDs [Gets_imp_knows_Spy RS analz.Inj]) 1);
    6.55 -qed "OR4_analz_knows_Spy";
    6.56 -
    6.57 -Goal "Says Server B {|X, Crypt K' {|NB, a, Agent B, K|}|} \\<in> set evs \
    6.58 -\     ==> K \\<in> parts (knows Spy evs)";
    6.59 -by (Blast_tac 1);
    6.60 -qed "Oops_parts_knows_Spy";
    6.61 -
    6.62 -bind_thm ("OR4_parts_knows_Spy",
    6.63 -          OR4_analz_knows_Spy RS (impOfSubs analz_subset_parts));
    6.64 -
    6.65 -(*For proving the easier theorems about X \\<notin> parts (knows Spy evs).*)
    6.66 -fun parts_induct_tac i = 
    6.67 -    etac otway.induct i			THEN 
    6.68 -    ftac Oops_parts_knows_Spy (i+7) THEN
    6.69 -    ftac OR4_parts_knows_Spy (i+6) THEN
    6.70 -    prove_simple_subgoals_tac  i;
    6.71 -
    6.72 -
    6.73 -(** Theorems of the form X \\<notin> parts (knows Spy evs) imply that NOBODY
    6.74 -    sends messages containing X! **)
    6.75 -
    6.76 -(*Spy never sees a good agent's shared key!*)
    6.77 -Goal "evs \\<in> otway ==> (Key (shrK A) \\<in> parts (knows Spy evs)) = (A \\<in> bad)";
    6.78 -by (parts_induct_tac 1);
    6.79 -by (ALLGOALS Blast_tac);
    6.80 -qed "Spy_see_shrK";
    6.81 -Addsimps [Spy_see_shrK];
    6.82 -
    6.83 -Goal "evs \\<in> otway ==> (Key (shrK A) \\<in> analz (knows Spy evs)) = (A \\<in> bad)";
    6.84 -by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset()));
    6.85 -qed "Spy_analz_shrK";
    6.86 -Addsimps [Spy_analz_shrK];
    6.87 -
    6.88 -AddSDs [Spy_see_shrK RSN (2, rev_iffD1), 
    6.89 -	Spy_analz_shrK RSN (2, rev_iffD1)];
    6.90 -
    6.91 -
    6.92 -(*** Proofs involving analz ***)
    6.93 -
    6.94 -(*Describes the form of K and NA when the Server sends this message.*)
    6.95 -Goal "[| Says Server B                                           \
    6.96 -\           {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
    6.97 -\             Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
    6.98 -\          \\<in> set evs;                                            \
    6.99 -\        evs \\<in> otway |]                                          \
   6.100 -\     ==> K \\<notin> range shrK & (\\<exists>i. NA = Nonce i) & (\\<exists>j. NB = Nonce j)";
   6.101 -by (etac rev_mp 1);
   6.102 -by (etac otway.induct 1);
   6.103 -by (ALLGOALS Asm_simp_tac);
   6.104 -by (Blast_tac 1);
   6.105 -qed "Says_Server_message_form";
   6.106 -
   6.107 -
   6.108 -(*For proofs involving analz.*)
   6.109 -val analz_knows_Spy_tac = 
   6.110 -    dtac OR4_analz_knows_Spy 7 THEN assume_tac 7 THEN
   6.111 -    ftac Says_Server_message_form 8 THEN assume_tac 8 THEN
   6.112 -    REPEAT ((eresolve_tac [exE, conjE] ORELSE' hyp_subst_tac) 8);
   6.113 -
   6.114 -
   6.115 -(****
   6.116 - The following is to prove theorems of the form
   6.117 -
   6.118 -  Key K \\<in> analz (insert (Key KAB) (knows Spy evs)) ==>
   6.119 -  Key K \\<in> analz (knows Spy evs)
   6.120 -
   6.121 - A more general formula must be proved inductively.
   6.122 -****)
   6.123 -
   6.124 -
   6.125 -(** Session keys are not used to encrypt other session keys **)
   6.126 -
   6.127 -(*The equality makes the induction hypothesis easier to apply*)
   6.128 -Goal "evs \\<in> otway ==>                                 \
   6.129 -\  ALL K KK. KK <= -(range shrK) -->                  \
   6.130 -\         (Key K \\<in> analz (Key`KK Un (knows Spy evs))) =  \
   6.131 -\         (K \\<in> KK | Key K \\<in> analz (knows Spy evs))";
   6.132 -by (etac otway.induct 1);
   6.133 -by analz_knows_Spy_tac;
   6.134 -by (REPEAT_FIRST (resolve_tac [allI, impI]));
   6.135 -by (REPEAT_FIRST (rtac analz_image_freshK_lemma ));
   6.136 -by (ALLGOALS (asm_simp_tac analz_image_freshK_ss));
   6.137 -(*Fake*) 
   6.138 -by (spy_analz_tac 1);
   6.139 -qed_spec_mp "analz_image_freshK";
   6.140 -
   6.141 -
   6.142 -Goal "[| evs \\<in> otway;  KAB \\<notin> range shrK |] ==>       \
   6.143 -\     Key K \\<in> analz (insert (Key KAB) (knows Spy evs)) =  \
   6.144 -\     (K = KAB | Key K \\<in> analz (knows Spy evs))";
   6.145 -by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
   6.146 -qed "analz_insert_freshK";
   6.147 -
   6.148 -
   6.149 -(*** The Key K uniquely identifies the Server's message. **)
   6.150 -
   6.151 -Goal "[| Says Server B                                           \
   6.152 -\         {|Crypt (shrK A) {|NA, Agent A, Agent B, K|},         \
   6.153 -\           Crypt (shrK B) {|NB, Agent A, Agent B, K|}|}        \
   6.154 -\        \\<in> set evs;                                             \
   6.155 -\       Says Server B'                                          \
   6.156 -\         {|Crypt (shrK A') {|NA', Agent A', Agent B', K|},     \
   6.157 -\           Crypt (shrK B') {|NB', Agent A', Agent B', K|}|}    \
   6.158 -\        \\<in> set evs;                                             \
   6.159 -\       evs \\<in> otway |]                                          \
   6.160 -\    ==> A=A' & B=B' & NA=NA' & NB=NB'";
   6.161 -by (etac rev_mp 1);
   6.162 -by (etac rev_mp 1);
   6.163 -by (etac otway.induct 1);
   6.164 -by (ALLGOALS Asm_simp_tac);
   6.165 -(*Remaining cases: OR3 and OR4*)
   6.166 -by (REPEAT (Blast_tac 1)); 
   6.167 -qed "unique_session_keys";
   6.168 -
   6.169 -
   6.170 -
   6.171 -(**** Authenticity properties relating to NA ****)
   6.172 -
   6.173 -(*If the encrypted message appears then it originated with the Server!*)
   6.174 -Goal "[| A \\<notin> bad;  A \\<noteq> B;  evs \\<in> otway |]                 \
   6.175 -\     ==> Crypt (shrK A) {|NA, Agent A, Agent B, Key K|} \\<in> parts (knows Spy evs) \
   6.176 -\      --> (\\<exists>NB. Says Server B                                          \
   6.177 -\                   {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   6.178 -\                     Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   6.179 -\                   \\<in> set evs)";
   6.180 -by (parts_induct_tac 1);
   6.181 -by (Blast_tac 1);
   6.182 -by (ALLGOALS (asm_simp_tac (simpset() addsimps [ex_disj_distrib])));
   6.183 -(*OR3*)
   6.184 -by (Blast_tac 1);
   6.185 -qed_spec_mp "NA_Crypt_imp_Server_msg";
   6.186 -
   6.187 -
   6.188 -(*Corollary: if A receives B's OR4 message then it originated with the Server.
   6.189 -  Freshness may be inferred from nonce NA.*)
   6.190 -Goal "[| Gets A (Crypt (shrK A) {|NA, Agent A, Agent B, Key K|})  \
   6.191 -\         \\<in> set evs;                                                 \
   6.192 -\        A \\<notin> bad;  A \\<noteq> B;  evs \\<in> otway |]                          \
   6.193 -\     ==> \\<exists>NB. Says Server B                                       \
   6.194 -\                 {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},  \
   6.195 -\                   Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   6.196 -\                \\<in> set evs";
   6.197 -by (blast_tac (claset() addSIs [NA_Crypt_imp_Server_msg]) 1);
   6.198 -qed "A_trusts_OR4";
   6.199 -
   6.200 -
   6.201 -(** Crucial secrecy property: Spy does not see the keys sent in msg OR3
   6.202 -    Does not in itself guarantee security: an attack could violate 
   6.203 -    the premises, e.g. by having A=Spy **)
   6.204 -
   6.205 -Goal "[| A \\<notin> bad;  B \\<notin> bad;  evs \\<in> otway |]                   \
   6.206 -\     ==> Says Server B                                         \
   6.207 -\          {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   6.208 -\            Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   6.209 -\         \\<in> set evs -->                                         \
   6.210 -\         Notes Spy {|NA, NB, Key K|} \\<notin> set evs -->            \
   6.211 -\         Key K \\<notin> analz (knows Spy evs)";
   6.212 -by (etac otway.induct 1);
   6.213 -by analz_knows_Spy_tac;
   6.214 -by (ALLGOALS
   6.215 -    (asm_simp_tac (simpset() addcongs [conj_cong] 
   6.216 -                             addsimps [analz_insert_eq, analz_insert_freshK]
   6.217 -                                      @ pushes @ split_ifs)));
   6.218 -(*Oops*)
   6.219 -by (blast_tac (claset() addSDs [unique_session_keys]) 4);
   6.220 -(*OR4*) 
   6.221 -by (Blast_tac 3);
   6.222 -(*OR3*)
   6.223 -by (Blast_tac 2);
   6.224 -(*Fake*) 
   6.225 -by (spy_analz_tac 1);
   6.226 -val lemma = result() RS mp RS mp RSN(2,rev_notE);
   6.227 -
   6.228 -Goal "[| Says Server B                                           \
   6.229 -\           {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   6.230 -\             Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   6.231 -\          \\<in> set evs;                                            \
   6.232 -\        Notes Spy {|NA, NB, Key K|} \\<notin> set evs;                 \
   6.233 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> otway |]                    \
   6.234 -\     ==> Key K \\<notin> analz (knows Spy evs)";
   6.235 -by (ftac Says_Server_message_form 1 THEN assume_tac 1);
   6.236 -by (blast_tac (claset() addSEs [lemma]) 1);
   6.237 -qed "Spy_not_see_encrypted_key";
   6.238 -
   6.239 -
   6.240 -(*A's guarantee.  The Oops premise quantifies over NB because A cannot know
   6.241 -  what it is.*)
   6.242 -Goal "[| Gets A (Crypt (shrK A) {|NA, Agent A, Agent B, Key K|})  \
   6.243 -\         \\<in> set evs;                                                 \
   6.244 -\        ALL NB. Notes Spy {|NA, NB, Key K|} \\<notin> set evs;             \
   6.245 -\        A \\<notin> bad;  B \\<notin> bad;  A \\<noteq> B;  evs \\<in> otway |]               \
   6.246 -\     ==> Key K \\<notin> analz (knows Spy evs)";
   6.247 -by (blast_tac (claset() addSDs [A_trusts_OR4, Spy_not_see_encrypted_key]) 1);
   6.248 -qed "A_gets_good_key";
   6.249 -
   6.250 -
   6.251 -(**** Authenticity properties relating to NB ****)
   6.252 -
   6.253 -(*If the encrypted message appears then it originated with the Server!*)
   6.254 -Goal "[| B \\<notin> bad;  A \\<noteq> B;  evs \\<in> otway |]                              \
   6.255 -\ ==> Crypt (shrK B) {|NB, Agent A, Agent B, Key K|} \\<in> parts (knows Spy evs) \
   6.256 -\     --> (\\<exists>NA. Says Server B                                          \
   6.257 -\                  {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   6.258 -\                    Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   6.259 -\                  \\<in> set evs)";
   6.260 -by (parts_induct_tac 1);
   6.261 -by (Blast_tac 1);
   6.262 -by (ALLGOALS (asm_simp_tac (simpset() addsimps [ex_disj_distrib])));
   6.263 -(*OR3*)
   6.264 -by (Blast_tac 1);
   6.265 -qed_spec_mp "NB_Crypt_imp_Server_msg";
   6.266 -
   6.267 -
   6.268 -(*Guarantee for B: if it gets a well-formed certificate then the Server
   6.269 -  has sent the correct message in round 3.*)
   6.270 -Goal "[| Gets B {|X, Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   6.271 -\          \\<in> set evs;                                                    \
   6.272 -\        B \\<notin> bad;  A \\<noteq> B;  evs \\<in> otway |]                              \
   6.273 -\     ==> \\<exists>NA. Says Server B                                           \
   6.274 -\                  {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   6.275 -\                    Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   6.276 -\                  \\<in> set evs";
   6.277 -by (blast_tac (claset() addSIs [NB_Crypt_imp_Server_msg]) 1);
   6.278 -qed "B_trusts_OR3";
   6.279 -
   6.280 -
   6.281 -(*The obvious combination of B_trusts_OR3 with Spy_not_see_encrypted_key*)
   6.282 -Goal "[| Gets B {|X, Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   6.283 -\         \\<in> set evs;                                                     \
   6.284 -\        ALL NA. Notes Spy {|NA, NB, Key K|} \\<notin> set evs;                 \
   6.285 -\        A \\<notin> bad;  B \\<notin> bad;  A \\<noteq> B;  evs \\<in> otway |]                   \
   6.286 -\     ==> Key K \\<notin> analz (knows Spy evs)";
   6.287 -by (blast_tac (claset() addDs [B_trusts_OR3, Spy_not_see_encrypted_key]) 1);
   6.288 -qed "B_gets_good_key";
     7.1 --- a/src/HOL/Auth/OtwayRees_AN.thy	Wed Apr 11 11:53:54 2001 +0200
     7.2 +++ b/src/HOL/Auth/OtwayRees_AN.thy	Thu Apr 12 12:45:05 2001 +0200
     7.3 @@ -5,7 +5,7 @@
     7.4  
     7.5  Inductive relation "otway" for the Otway-Rees protocol.
     7.6  
     7.7 -Simplified version with minimal encryption but explicit messages
     7.8 +Abadi-Needham simplified version: minimal encryption, explicit messages
     7.9  
    7.10  Note that the formalization does not even assume that nonces are fresh.
    7.11  This is because the protocol does not rely on uniqueness of nonces for
    7.12 @@ -17,61 +17,298 @@
    7.13    IEEE Trans. SE 22 (1), 1996
    7.14  *)
    7.15  
    7.16 -OtwayRees_AN = Shared + 
    7.17 +theory OtwayRees_AN = Shared:
    7.18  
    7.19 -consts  otway   :: event list set
    7.20 +consts  otway   :: "event list set"
    7.21  inductive "otway"
    7.22 -  intrs 
    7.23 +  intros
    7.24           (*Initial trace is empty*)
    7.25 -    Nil  "[]: otway"
    7.26 +   Nil:  "[] \<in> otway"
    7.27  
    7.28           (*The spy MAY say anything he CAN say.  We do not expect him to
    7.29             invent new nonces here, but he can also use NS1.  Common to
    7.30             all similar protocols.*)
    7.31 -    Fake "[| evs \\<in> otway;  X \\<in> synth (analz (knows Spy evs)) |]
    7.32 -          ==> Says Spy B X  # evs \\<in> otway"
    7.33 +   Fake: "[| evsf \<in> otway;  X \<in> synth (analz (knows Spy evsf)) |]
    7.34 +          ==> Says Spy B X  # evsf \<in> otway"
    7.35  
    7.36           (*A message that has been sent can be received by the
    7.37             intended recipient.*)
    7.38 -    Reception "[| evsr \\<in> otway;  Says A B X \\<in>set evsr |]
    7.39 -               ==> Gets B X # evsr \\<in> otway"
    7.40 +   Reception: "[| evsr \<in> otway;  Says A B X \<in>set evsr |]
    7.41 +               ==> Gets B X # evsr \<in> otway"
    7.42  
    7.43           (*Alice initiates a protocol run*)
    7.44 -    OR1  "[| evs1 \\<in> otway |]
    7.45 -          ==> Says A B {|Agent A, Agent B, Nonce NA|} # evs1 \\<in> otway"
    7.46 +   OR1:  "evs1 \<in> otway
    7.47 +          ==> Says A B {|Agent A, Agent B, Nonce NA|} # evs1 \<in> otway"
    7.48  
    7.49           (*Bob's response to Alice's message.*)
    7.50 -    OR2  "[| evs2 \\<in> otway;  
    7.51 -             Gets B {|Agent A, Agent B, Nonce NA|} \\<in>set evs2 |]
    7.52 +   OR2:  "[| evs2 \<in> otway;
    7.53 +             Gets B {|Agent A, Agent B, Nonce NA|} \<in>set evs2 |]
    7.54            ==> Says B Server {|Agent A, Agent B, Nonce NA, Nonce NB|}
    7.55 -                 # evs2 \\<in> otway"
    7.56 +                 # evs2 \<in> otway"
    7.57  
    7.58           (*The Server receives Bob's message.  Then he sends a new
    7.59             session key to Bob with a packet for forwarding to Alice.*)
    7.60 -    OR3  "[| evs3 \\<in> otway;  Key KAB \\<notin> used evs3;
    7.61 +   OR3:  "[| evs3 \<in> otway;  Key KAB \<notin> used evs3;
    7.62               Gets Server {|Agent A, Agent B, Nonce NA, Nonce NB|}
    7.63 -               \\<in>set evs3 |]
    7.64 -          ==> Says Server B 
    7.65 +               \<in>set evs3 |]
    7.66 +          ==> Says Server B
    7.67                 {|Crypt (shrK A) {|Nonce NA, Agent A, Agent B, Key KAB|},
    7.68                   Crypt (shrK B) {|Nonce NB, Agent A, Agent B, Key KAB|}|}
    7.69 -              # evs3 \\<in> otway"
    7.70 +              # evs3 \<in> otway"
    7.71  
    7.72           (*Bob receives the Server's (?) message and compares the Nonces with
    7.73  	   those in the message he previously sent the Server.
    7.74 -           Need B \\<noteq> Server because we allow messages to self.*)
    7.75 -    OR4  "[| evs4 \\<in> otway;  B \\<noteq> Server; 
    7.76 -             Says B Server {|Agent A, Agent B, Nonce NA, Nonce NB|} \\<in>set evs4;
    7.77 +           Need B \<noteq> Server because we allow messages to self.*)
    7.78 +   OR4:  "[| evs4 \<in> otway;  B \<noteq> Server;
    7.79 +             Says B Server {|Agent A, Agent B, Nonce NA, Nonce NB|} \<in>set evs4;
    7.80               Gets B {|X, Crypt(shrK B){|Nonce NB,Agent A,Agent B,Key K|}|}
    7.81 -               \\<in>set evs4 |]
    7.82 -          ==> Says B A X # evs4 \\<in> otway"
    7.83 +               \<in>set evs4 |]
    7.84 +          ==> Says B A X # evs4 \<in> otway"
    7.85  
    7.86           (*This message models possible leaks of session keys.  The nonces
    7.87             identify the protocol run.  B is not assumed to know shrK A.*)
    7.88 -    Oops "[| evso \\<in> otway;  
    7.89 -             Says Server B 
    7.90 -                      {|Crypt (shrK A) {|Nonce NA, Agent A, Agent B, Key K|}, 
    7.91 +   Oops: "[| evso \<in> otway;
    7.92 +             Says Server B
    7.93 +                      {|Crypt (shrK A) {|Nonce NA, Agent A, Agent B, Key K|},
    7.94                          Crypt (shrK B) {|Nonce NB, Agent A, Agent B, Key K|}|}
    7.95 -               \\<in>set evso |]
    7.96 -          ==> Notes Spy {|Nonce NA, Nonce NB, Key K|} # evso \\<in> otway"
    7.97 +               \<in>set evso |]
    7.98 +          ==> Notes Spy {|Nonce NA, Nonce NB, Key K|} # evso \<in> otway"
    7.99 +
   7.100 +
   7.101 +declare Says_imp_knows_Spy [THEN analz.Inj, dest]
   7.102 +declare parts.Body  [dest]
   7.103 +declare analz_into_parts [dest]
   7.104 +declare Fake_parts_insert_in_Un  [dest]
   7.105 +
   7.106 +
   7.107 +(*A "possibility property": there are traces that reach the end*)
   7.108 +lemma "B \<noteq> Server
   7.109 +      ==> \<exists>K. \<exists>evs \<in> otway.
   7.110 +           Says B A (Crypt (shrK A) {|Nonce NA, Agent A, Agent B, Key K|})
   7.111 +             \<in> set evs"
   7.112 +apply (intro exI bexI)
   7.113 +apply (rule_tac [2] otway.Nil
   7.114 +                    [THEN otway.OR1, THEN otway.Reception,
   7.115 +                     THEN otway.OR2, THEN otway.Reception,
   7.116 +                     THEN otway.OR3, THEN otway.Reception, THEN otway.OR4])
   7.117 +apply possibility
   7.118 +done
   7.119 +
   7.120 +lemma Gets_imp_Says [dest!]:
   7.121 +     "[| Gets B X \<in> set evs; evs \<in> otway |] ==> \<exists>A. Says A B X \<in> set evs"
   7.122 +by (erule rev_mp, erule otway.induct, auto)
   7.123 +
   7.124 +
   7.125 +(**** Inductive proofs about otway ****)
   7.126 +
   7.127 +(** For reasoning about the encrypted portion of messages **)
   7.128 +
   7.129 +lemma OR4_analz_knows_Spy:
   7.130 +     "[| Gets B {|X, Crypt(shrK B) X'|} \<in> set evs;  evs \<in> otway |]
   7.131 +      ==> X \<in> analz (knows Spy evs)"
   7.132 +by blast
   7.133 +
   7.134 +
   7.135 +(** Theorems of the form X \<notin> parts (knows Spy evs) imply that NOBODY
   7.136 +    sends messages containing X! **)
   7.137 +
   7.138 +(*Spy never sees a good agent's shared key!*)
   7.139 +lemma Spy_see_shrK [simp]:
   7.140 +     "evs \<in> otway ==> (Key (shrK A) \<in> parts (knows Spy evs)) = (A \<in> bad)"
   7.141 +apply (erule otway.induct, simp_all)
   7.142 +apply blast+
   7.143 +done
   7.144 +
   7.145 +lemma Spy_analz_shrK [simp]:
   7.146 +     "evs \<in> otway ==> (Key (shrK A) \<in> analz (knows Spy evs)) = (A \<in> bad)"
   7.147 +by auto
   7.148 +
   7.149 +lemma Spy_see_shrK_D [dest!]:
   7.150 +     "[|Key (shrK A) \<in> parts (knows Spy evs);  evs \<in> otway|] ==> A \<in> bad"
   7.151 +by (blast dest: Spy_see_shrK)
   7.152 +
   7.153 +
   7.154 +(*** Proofs involving analz ***)
   7.155 +
   7.156 +(*Describes the form of K and NA when the Server sends this message.*)
   7.157 +lemma Says_Server_message_form:
   7.158 +     "[| Says Server B
   7.159 +            {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},
   7.160 +              Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}
   7.161 +           \<in> set evs;
   7.162 +         evs \<in> otway |]
   7.163 +      ==> K \<notin> range shrK & (\<exists>i. NA = Nonce i) & (\<exists>j. NB = Nonce j)"
   7.164 +apply (erule rev_mp)
   7.165 +apply (erule otway.induct)
   7.166 +apply simp_all
   7.167 +apply blast
   7.168 +done
   7.169 +
   7.170 +
   7.171 +
   7.172 +(****
   7.173 + The following is to prove theorems of the form
   7.174 +
   7.175 +  Key K \<in> analz (insert (Key KAB) (knows Spy evs)) ==>
   7.176 +  Key K \<in> analz (knows Spy evs)
   7.177 +
   7.178 + A more general formula must be proved inductively.
   7.179 +****)
   7.180 +
   7.181 +
   7.182 +(** Session keys are not used to encrypt other session keys **)
   7.183 +
   7.184 +(*The equality makes the induction hypothesis easier to apply*)
   7.185 +lemma analz_image_freshK [rule_format]:
   7.186 + "evs \<in> otway ==>
   7.187 +   \<forall>K KK. KK <= -(range shrK) -->
   7.188 +          (Key K \<in> analz (Key`KK Un (knows Spy evs))) =
   7.189 +          (K \<in> KK | Key K \<in> analz (knows Spy evs))"
   7.190 +apply (erule otway.induct, force)
   7.191 +apply (frule_tac [7] Says_Server_message_form)
   7.192 +apply (drule_tac [6] OR4_analz_knows_Spy)
   7.193 +apply analz_freshK
   7.194 +apply spy_analz
   7.195 +done
   7.196 +
   7.197 +lemma analz_insert_freshK:
   7.198 +  "[| evs \<in> otway;  KAB \<notin> range shrK |] ==>
   7.199 +      Key K \<in> analz (insert (Key KAB) (knows Spy evs)) =
   7.200 +      (K = KAB | Key K \<in> analz (knows Spy evs))"
   7.201 +by (simp only: analz_image_freshK analz_image_freshK_simps)
   7.202 +
   7.203 +
   7.204 +(*** The Key K uniquely identifies the Server's message. **)
   7.205 +
   7.206 +lemma unique_session_keys:
   7.207 +     "[| Says Server B
   7.208 +          {|Crypt (shrK A) {|NA, Agent A, Agent B, K|},
   7.209 +            Crypt (shrK B) {|NB, Agent A, Agent B, K|}|}
   7.210 +         \<in> set evs;
   7.211 +        Says Server B'
   7.212 +          {|Crypt (shrK A') {|NA', Agent A', Agent B', K|},
   7.213 +            Crypt (shrK B') {|NB', Agent A', Agent B', K|}|}
   7.214 +         \<in> set evs;
   7.215 +        evs \<in> otway |]
   7.216 +     ==> A=A' & B=B' & NA=NA' & NB=NB'"
   7.217 +apply (erule rev_mp, erule rev_mp, erule otway.induct)
   7.218 +apply simp_all
   7.219 +(*Remaining cases: OR3 and OR4*)
   7.220 +apply blast+
   7.221 +done
   7.222 +
   7.223 +
   7.224 +(**** Authenticity properties relating to NA ****)
   7.225 +
   7.226 +(*If the encrypted message appears then it originated with the Server!*)
   7.227 +lemma NA_Crypt_imp_Server_msg [rule_format]:
   7.228 +    "[| A \<notin> bad;  A \<noteq> B;  evs \<in> otway |]
   7.229 +     ==> Crypt (shrK A) {|NA, Agent A, Agent B, Key K|} \<in> parts (knows Spy evs)
   7.230 +       --> (\<exists>NB. Says Server B
   7.231 +                    {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},
   7.232 +                      Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}
   7.233 +                    \<in> set evs)"
   7.234 +apply (erule otway.induct, force)
   7.235 +apply (simp_all add: ex_disj_distrib)
   7.236 +(*Fake, OR3*)
   7.237 +apply blast+;
   7.238 +done
   7.239 +
   7.240 +
   7.241 +(*Corollary: if A receives B's OR4 message then it originated with the Server.
   7.242 +  Freshness may be inferred from nonce NA.*)
   7.243 +lemma A_trusts_OR4:
   7.244 +     "[| Says B' A (Crypt (shrK A) {|NA, Agent A, Agent B, Key K|}) \<in> set evs;
   7.245 +         A \<notin> bad;  A \<noteq> B;  evs \<in> otway |]
   7.246 +      ==> \<exists>NB. Says Server B
   7.247 +                  {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},
   7.248 +                    Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}
   7.249 +                 \<in> set evs"
   7.250 +by (blast intro!: NA_Crypt_imp_Server_msg)
   7.251 +
   7.252 +
   7.253 +(** Crucial secrecy property: Spy does not see the keys sent in msg OR3
   7.254 +    Does not in itself guarantee security: an attack could violate
   7.255 +    the premises, e.g. by having A=Spy **)
   7.256 +
   7.257 +lemma secrecy_lemma:
   7.258 +     "[| A \<notin> bad;  B \<notin> bad;  evs \<in> otway |]
   7.259 +      ==> Says Server B
   7.260 +           {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},
   7.261 +             Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}
   7.262 +          \<in> set evs -->
   7.263 +          Notes Spy {|NA, NB, Key K|} \<notin> set evs -->
   7.264 +          Key K \<notin> analz (knows Spy evs)"
   7.265 +apply (erule otway.induct, force)
   7.266 +apply (frule_tac [7] Says_Server_message_form)
   7.267 +apply (drule_tac [6] OR4_analz_knows_Spy)
   7.268 +apply (simp_all add: analz_insert_eq analz_insert_freshK pushes)
   7.269 +apply spy_analz  (*Fake*)
   7.270 +(*OR3, OR4, Oops*)
   7.271 +apply (blast dest: unique_session_keys)+
   7.272 +done
   7.273 +
   7.274 +
   7.275 +lemma Spy_not_see_encrypted_key:
   7.276 +     "[| Says Server B
   7.277 +            {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},
   7.278 +              Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}
   7.279 +           \<in> set evs;
   7.280 +         Notes Spy {|NA, NB, Key K|} \<notin> set evs;
   7.281 +         A \<notin> bad;  B \<notin> bad;  evs \<in> otway |]
   7.282 +      ==> Key K \<notin> analz (knows Spy evs)"
   7.283 +by (blast dest: Says_Server_message_form secrecy_lemma)
   7.284 +
   7.285 +
   7.286 +(*A's guarantee.  The Oops premise quantifies over NB because A cannot know
   7.287 +  what it is.*)
   7.288 +lemma A_gets_good_key:
   7.289 +     "[| Says B' A (Crypt (shrK A) {|NA, Agent A, Agent B, Key K|}) \<in> set evs;
   7.290 +         \<forall>NB. Notes Spy {|NA, NB, Key K|} \<notin> set evs;
   7.291 +         A \<notin> bad;  B \<notin> bad;  A \<noteq> B;  evs \<in> otway |]
   7.292 +      ==> Key K \<notin> analz (knows Spy evs)"
   7.293 +by (blast dest!: A_trusts_OR4 Spy_not_see_encrypted_key)
   7.294 +
   7.295 +
   7.296 +
   7.297 +(**** Authenticity properties relating to NB ****)
   7.298 +
   7.299 +(*If the encrypted message appears then it originated with the Server!*)
   7.300 +
   7.301 +lemma NB_Crypt_imp_Server_msg [rule_format]:
   7.302 + "[| B \<notin> bad;  A \<noteq> B;  evs \<in> otway |]
   7.303 +  ==> Crypt (shrK B) {|NB, Agent A, Agent B, Key K|} \<in> parts (knows Spy evs)
   7.304 +      --> (\<exists>NA. Says Server B
   7.305 +                   {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},
   7.306 +                     Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}
   7.307 +                   \<in> set evs)"
   7.308 +apply (erule otway.induct, force, simp_all add: ex_disj_distrib)
   7.309 +(*Fake, OR3*)
   7.310 +apply blast+;
   7.311 +done
   7.312 +
   7.313 +
   7.314 +
   7.315 +(*Guarantee for B: if it gets a well-formed certificate then the Server
   7.316 +  has sent the correct message in round 3.*)
   7.317 +lemma B_trusts_OR3:
   7.318 +     "[| Says S B {|X, Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}
   7.319 +           \<in> set evs;
   7.320 +         B \<notin> bad;  A \<noteq> B;  evs \<in> otway |]
   7.321 +      ==> \<exists>NA. Says Server B
   7.322 +                   {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},
   7.323 +                     Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}
   7.324 +                   \<in> set evs"
   7.325 +by (blast intro!: NB_Crypt_imp_Server_msg)
   7.326 +
   7.327 +
   7.328 +(*The obvious combination of B_trusts_OR3 with Spy_not_see_encrypted_key*)
   7.329 +lemma B_gets_good_key:
   7.330 +     "[| Gets B {|X, Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}
   7.331 +          \<in> set evs;
   7.332 +         \<forall>NA. Notes Spy {|NA, NB, Key K|} \<notin> set evs;
   7.333 +         A \<notin> bad;  B \<notin> bad;  A \<noteq> B;  evs \<in> otway |]
   7.334 +      ==> Key K \<notin> analz (knows Spy evs)"
   7.335 +by (blast dest: B_trusts_OR3 Spy_not_see_encrypted_key)
   7.336  
   7.337  end
     8.1 --- a/src/HOL/Auth/OtwayRees_Bad.ML	Wed Apr 11 11:53:54 2001 +0200
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,261 +0,0 @@
     8.4 -(*  Title:      HOL/Auth/OtwayRees_Bad
     8.5 -    ID:         $Id$
     8.6 -    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     8.7 -    Copyright   1996  University of Cambridge
     8.8 -
     8.9 -Inductive relation "otway" for the Otway-Rees protocol.
    8.10 -
    8.11 -The FAULTY version omitting encryption of Nonce NB, as suggested on page 247 of
    8.12 -  Burrows, Abadi and Needham.  A Logic of Authentication.
    8.13 -  Proc. Royal Soc. 426 (1989)
    8.14 -
    8.15 -This file illustrates the consequences of such errors.  We can still prove
    8.16 -impressive-looking properties such as Spy_not_see_encrypted_key, yet the
    8.17 -protocol is open to a middleperson attack.  Attempting to prove some key lemmas
    8.18 -indicates the possibility of this attack.
    8.19 -*)
    8.20 -
    8.21 -AddDs  [Says_imp_knows_Spy RS parts.Inj, parts.Body];
    8.22 -AddDs  [impOfSubs analz_subset_parts, impOfSubs Fake_parts_insert];
    8.23 -
    8.24 -(*A "possibility property": there are traces that reach the end*)
    8.25 -Goal "B \\<noteq> Server   \
    8.26 -\     ==> \\<exists>K. \\<exists>NA. \\<exists>evs \\<in> otway.          \
    8.27 -\           Says B A {|Nonce NA, Crypt (shrK A) {|Nonce NA, Key K|}|} \
    8.28 -\             \\<in> set evs";
    8.29 -by (REPEAT (resolve_tac [exI,bexI] 1));
    8.30 -by (rtac (otway.Nil RS 
    8.31 -          otway.OR1 RS otway.Reception RS
    8.32 -          otway.OR2 RS otway.Reception RS 
    8.33 -          otway.OR3 RS otway.Reception RS otway.OR4) 2);
    8.34 -by possibility_tac;
    8.35 -result();
    8.36 -
    8.37 -Goal "[| Gets B X \\<in> set evs; evs \\<in> otway |] ==> \\<exists>A. Says A B X \\<in> set evs";
    8.38 -by (etac rev_mp 1);
    8.39 -by (etac otway.induct 1);
    8.40 -by Auto_tac;
    8.41 -qed"Gets_imp_Says";
    8.42 -
    8.43 -(*Must be proved separately for each protocol*)
    8.44 -Goal "[| Gets B X \\<in> set evs; evs \\<in> otway |]  ==> X \\<in> knows Spy evs";
    8.45 -by (blast_tac (claset() addSDs [Gets_imp_Says, Says_imp_knows_Spy]) 1);
    8.46 -qed"Gets_imp_knows_Spy";
    8.47 -AddDs [Gets_imp_knows_Spy RS parts.Inj];
    8.48 -
    8.49 -
    8.50 -(**** Inductive proofs about otway ****)
    8.51 -
    8.52 -
    8.53 -(** For reasoning about the encrypted portion of messages **)
    8.54 -
    8.55 -Goal "[| Gets B {|N, Agent A, Agent B, X|} \\<in> set evs;  evs \\<in> otway |] \
    8.56 -\     ==> X \\<in> analz (knows Spy evs)";
    8.57 -by (blast_tac (claset() addSDs [Gets_imp_knows_Spy RS analz.Inj]) 1);
    8.58 -qed "OR2_analz_knows_Spy";
    8.59 -
    8.60 -Goal "[| Gets B {|N, X, Crypt (shrK B) X'|} \\<in> set evs;  evs \\<in> otway |] \
    8.61 -\     ==> X \\<in> analz (knows Spy evs)";
    8.62 -by (blast_tac (claset() addSDs [Gets_imp_knows_Spy RS analz.Inj]) 1);
    8.63 -qed "OR4_analz_knows_Spy";
    8.64 -
    8.65 -Goal "Says Server B {|NA, X, Crypt K' {|NB,K|}|} \\<in> set evs \
    8.66 -\     ==> K \\<in> parts (knows Spy evs)";
    8.67 -by (Blast_tac 1);
    8.68 -qed "Oops_parts_knows_Spy";
    8.69 -
    8.70 -bind_thm ("OR2_parts_knows_Spy",
    8.71 -          OR2_analz_knows_Spy RS (impOfSubs analz_subset_parts));
    8.72 -bind_thm ("OR4_parts_knows_Spy",
    8.73 -          OR4_analz_knows_Spy RS (impOfSubs analz_subset_parts));
    8.74 -
    8.75 -(*For proving the easier theorems about X \\<notin> parts (knows Spy evs).*)
    8.76 -fun parts_induct_tac i = 
    8.77 -    etac otway.induct i			THEN 
    8.78 -    ftac Oops_parts_knows_Spy (i+7) THEN
    8.79 -    ftac OR4_parts_knows_Spy (i+6) THEN
    8.80 -    ftac OR2_parts_knows_Spy (i+4) THEN 
    8.81 -    prove_simple_subgoals_tac  i;
    8.82 -
    8.83 -
    8.84 -(** Theorems of the form X \\<notin> parts (knows Spy evs) imply that NOBODY
    8.85 -    sends messages containing X! **)
    8.86 -
    8.87 -(*Spy never sees a good agent's shared key!*)
    8.88 -Goal "evs \\<in> otway ==> (Key (shrK A) \\<in> parts (knows Spy evs)) = (A \\<in> bad)";
    8.89 -by (parts_induct_tac 1);
    8.90 -by (ALLGOALS Blast_tac);
    8.91 -qed "Spy_see_shrK";
    8.92 -Addsimps [Spy_see_shrK];
    8.93 -
    8.94 -Goal "evs \\<in> otway ==> (Key (shrK A) \\<in> analz (knows Spy evs)) = (A \\<in> bad)";
    8.95 -by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset()));
    8.96 -qed "Spy_analz_shrK";
    8.97 -Addsimps [Spy_analz_shrK];
    8.98 -
    8.99 -AddSDs [Spy_see_shrK RSN (2, rev_iffD1), 
   8.100 -	Spy_analz_shrK RSN (2, rev_iffD1)];
   8.101 -
   8.102 -
   8.103 -(*** Proofs involving analz ***)
   8.104 -
   8.105 -(*Describes the form of K and NA when the Server sends this message.  Also
   8.106 -  for Oops case.*)
   8.107 -Goal "[| Says Server B {|NA, X, Crypt (shrK B) {|NB, Key K|}|} \\<in> set evs; \
   8.108 -\        evs \\<in> otway |]                                           \
   8.109 -\  ==> K \\<notin> range shrK & (\\<exists>i. NA = Nonce i) & (\\<exists>j. NB = Nonce j)";
   8.110 -by (etac rev_mp 1);
   8.111 -by (etac otway.induct 1);
   8.112 -by (ALLGOALS Simp_tac);
   8.113 -by (ALLGOALS Blast_tac);
   8.114 -qed "Says_Server_message_form";
   8.115 -
   8.116 -
   8.117 -(*For proofs involving analz.*)
   8.118 -val analz_knows_Spy_tac = 
   8.119 -    dtac OR2_analz_knows_Spy 5 THEN assume_tac 5 THEN 
   8.120 -    dtac OR4_analz_knows_Spy 7 THEN assume_tac 7 THEN
   8.121 -    ftac Says_Server_message_form 8 THEN assume_tac 8 THEN
   8.122 -    REPEAT ((eresolve_tac [exE, conjE] ORELSE' hyp_subst_tac) 8);
   8.123 -
   8.124 -
   8.125 -(****
   8.126 - The following is to prove theorems of the form
   8.127 -
   8.128 -  Key K \\<in> analz (insert (Key KAB) (knows Spy evs)) ==>
   8.129 -  Key K \\<in> analz (knows Spy evs)
   8.130 -
   8.131 - A more general formula must be proved inductively.
   8.132 -****)
   8.133 -
   8.134 -
   8.135 -(** Session keys are not used to encrypt other session keys **)
   8.136 -
   8.137 -(*The equality makes the induction hypothesis easier to apply*)
   8.138 -Goal "evs \\<in> otway ==>                                 \
   8.139 -\  \\<forall>K KK. KK <= - (range shrK) -->                 \
   8.140 -\         (Key K \\<in> analz (Key`KK Un (knows Spy evs))) =  \
   8.141 -\         (K \\<in> KK | Key K \\<in> analz (knows Spy evs))";
   8.142 -by (etac otway.induct 1);
   8.143 -by analz_knows_Spy_tac;
   8.144 -by (REPEAT_FIRST (resolve_tac [allI, impI]));
   8.145 -by (REPEAT_FIRST (rtac analz_image_freshK_lemma ));
   8.146 -by (ALLGOALS (asm_simp_tac analz_image_freshK_ss));
   8.147 -(*Fake*) 
   8.148 -by (spy_analz_tac 1);
   8.149 -qed_spec_mp "analz_image_freshK";
   8.150 -
   8.151 -
   8.152 -Goal "[| evs \\<in> otway;  KAB \\<notin> range shrK |] ==>       \
   8.153 -\     Key K \\<in> analz (insert (Key KAB) (knows Spy evs)) =  \
   8.154 -\     (K = KAB | Key K \\<in> analz (knows Spy evs))";
   8.155 -by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
   8.156 -qed "analz_insert_freshK";
   8.157 -
   8.158 -
   8.159 -(*** The Key K uniquely identifies the Server's  message. **)
   8.160 -
   8.161 -Goal "[| Says Server B {|NA, X, Crypt (shrK B) {|NB, K|}|}   \\<in> set evs; \ 
   8.162 -\        Says Server B' {|NA',X',Crypt (shrK B') {|NB',K|}|} \\<in> set evs; \
   8.163 -\        evs \\<in> otway |] ==> X=X' & B=B' & NA=NA' & NB=NB'";
   8.164 -by (etac rev_mp 1);
   8.165 -by (etac rev_mp 1);
   8.166 -by (etac otway.induct 1);
   8.167 -by (ALLGOALS Asm_simp_tac);
   8.168 -(*Remaining cases: OR3 and OR4*)
   8.169 -by (REPEAT (Blast_tac 1)); 
   8.170 -qed "unique_session_keys";
   8.171 -
   8.172 -
   8.173 -(** Crucial secrecy property: Spy does not see the keys sent in msg OR3
   8.174 -    Does not in itself guarantee security: an attack could violate 
   8.175 -    the premises, e.g. by having A=Spy **)
   8.176 -
   8.177 -Goal "[| A \\<notin> bad;  B \\<notin> bad;  evs \\<in> otway |]                      \
   8.178 -\     ==> Says Server B                                            \
   8.179 -\           {|NA, Crypt (shrK A) {|NA, Key K|},                    \
   8.180 -\             Crypt (shrK B) {|NB, Key K|}|} \\<in> set evs -->         \
   8.181 -\         Notes Spy {|NA, NB, Key K|} \\<notin> set evs -->               \
   8.182 -\         Key K \\<notin> analz (knows Spy evs)";
   8.183 -by (etac otway.induct 1);
   8.184 -by analz_knows_Spy_tac;
   8.185 -by (ALLGOALS
   8.186 -    (asm_simp_tac (simpset() addcongs [conj_cong] 
   8.187 -                             addsimps [analz_insert_eq, analz_insert_freshK]
   8.188 -                                      @ pushes @ split_ifs)));
   8.189 -(*Oops*)
   8.190 -by (blast_tac (claset() addSDs [unique_session_keys]) 4);
   8.191 -(*OR4*) 
   8.192 -by (Blast_tac 3);
   8.193 -(*OR3*)
   8.194 -by (Blast_tac 2);
   8.195 -(*Fake*) 
   8.196 -by (spy_analz_tac 1);
   8.197 -val lemma = result() RS mp RS mp RSN(2,rev_notE);
   8.198 -
   8.199 -Goal "[| Says Server B                                           \
   8.200 -\         {|NA, Crypt (shrK A) {|NA, Key K|},                    \
   8.201 -\               Crypt (shrK B) {|NB, Key K|}|} \\<in> set evs;        \
   8.202 -\        Notes Spy {|NA, NB, Key K|} \\<notin> set evs;                 \
   8.203 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> otway |]                    \
   8.204 -\     ==> Key K \\<notin> analz (knows Spy evs)";
   8.205 -by (ftac Says_Server_message_form 1 THEN assume_tac 1);
   8.206 -by (blast_tac (claset() addSEs [lemma]) 1);
   8.207 -qed "Spy_not_see_encrypted_key";
   8.208 -
   8.209 -
   8.210 -(*** Attempting to prove stronger properties ***)
   8.211 -
   8.212 -(*Only OR1 can have caused such a part of a message to appear.
   8.213 -  The premise A \\<noteq> B prevents OR2's similar-looking cryptogram from being
   8.214 -  picked up.  Original Otway-Rees doesn't need it.*)
   8.215 -Goal "[| A \\<notin> bad;  A \\<noteq> B;  evs \\<in> otway |]                \
   8.216 -\     ==> Crypt (shrK A) {|NA, Agent A, Agent B|} \\<in> parts (knows Spy evs) --> \
   8.217 -\         Says A B {|NA, Agent A, Agent B,                  \
   8.218 -\                    Crypt (shrK A) {|NA, Agent A, Agent B|}|}  \\<in> set evs";
   8.219 -by (parts_induct_tac 1);
   8.220 -by (ALLGOALS Blast_tac);
   8.221 -qed_spec_mp "Crypt_imp_OR1";
   8.222 -
   8.223 -
   8.224 -(*Crucial property: If the encrypted message appears, and A has used NA
   8.225 -  to start a run, then it originated with the Server!
   8.226 -  The premise A \\<noteq> B allows use of Crypt_imp_OR1*)
   8.227 -(*Only it is FALSE.  Somebody could make a fake message to Server
   8.228 -          substituting some other nonce NA' for NB.*)
   8.229 -Goal "[| A \\<notin> bad;  A \\<noteq> B;  evs \\<in> otway |]                                \
   8.230 -\     ==> Crypt (shrK A) {|NA, Key K|} \\<in> parts (knows Spy evs) -->    \
   8.231 -\         Says A B {|NA, Agent A, Agent B,                        \
   8.232 -\                    Crypt (shrK A) {|NA, Agent A, Agent B|}|}    \
   8.233 -\          \\<in> set evs -->                                          \
   8.234 -\         (\\<exists>B NB. Says Server B                                 \
   8.235 -\              {|NA,                                              \
   8.236 -\                Crypt (shrK A) {|NA, Key K|},                    \
   8.237 -\                Crypt (shrK B) {|NB, Key K|}|}  \\<in> set evs)";
   8.238 -by (parts_induct_tac 1);
   8.239 -(*Fake*)
   8.240 -by (Blast_tac 1);
   8.241 -(*OR1: it cannot be a new Nonce, contradiction.*)
   8.242 -by (Blast_tac 1);
   8.243 -(*OR3 and OR4*)
   8.244 -by (ALLGOALS (asm_simp_tac (simpset() addsimps [ex_disj_distrib])));
   8.245 -by (ALLGOALS Clarify_tac);
   8.246 -(*OR4*)
   8.247 -by (blast_tac (claset() addSIs [Crypt_imp_OR1]) 2);
   8.248 -(*OR3*)  (** LEVEL 5 **)
   8.249 -(*The hypotheses at this point suggest an attack in which nonce NB is used
   8.250 -  in two different roles:
   8.251 -          Gets Server
   8.252 -           {|Nonce NA, Agent Aa, Agent A,
   8.253 -             Crypt (shrK Aa) {|Nonce NA, Agent Aa, Agent A|}, Nonce NB,
   8.254 -             Crypt (shrK A) {|Nonce NA, Agent Aa, Agent A|}|}
   8.255 -          \\<in> set evs3;
   8.256 -          Says A B
   8.257 -           {|Nonce NB, Agent A, Agent B,
   8.258 -             Crypt (shrK A) {|Nonce NB, Agent A, Agent B|}|}
   8.259 -          \\<in> set evs3;
   8.260 -*)
   8.261 -writeln "GIVE UP! on NA_Crypt_imp_Server_msg";
   8.262 -
   8.263 -
   8.264 -(*Thus the key property A_can_trust probably fails too.*)
     9.1 --- a/src/HOL/Auth/OtwayRees_Bad.thy	Wed Apr 11 11:53:54 2001 +0200
     9.2 +++ b/src/HOL/Auth/OtwayRees_Bad.thy	Thu Apr 12 12:45:05 2001 +0200
     9.3 @@ -8,75 +8,304 @@
     9.4  The FAULTY version omitting encryption of Nonce NB, as suggested on page 247 of
     9.5    Burrows, Abadi and Needham.  A Logic of Authentication.
     9.6    Proc. Royal Soc. 426 (1989)
     9.7 +
     9.8 +This file illustrates the consequences of such errors.  We can still prove
     9.9 +impressive-looking properties such as Spy_not_see_encrypted_key, yet the
    9.10 +protocol is open to a middleperson attack.  Attempting to prove some key lemmas
    9.11 +indicates the possibility of this attack.
    9.12  *)
    9.13  
    9.14 -OtwayRees_Bad = Shared + 
    9.15 -
    9.16 -consts  otway   :: event list set
    9.17 +theory OtwayRees_Bad = Shared:
    9.18  
    9.19 -inductive otway
    9.20 -  intrs 
    9.21 +consts  otway   :: "event list set"
    9.22 +inductive "otway"
    9.23 +  intros
    9.24           (*Initial trace is empty*)
    9.25 -    Nil  "[] \\<in> otway"
    9.26 +   Nil:  "[] \<in> otway"
    9.27  
    9.28           (*The spy MAY say anything he CAN say.  We do not expect him to
    9.29             invent new nonces here, but he can also use NS1.  Common to
    9.30             all similar protocols.*)
    9.31 -    Fake "[| evsf \\<in> otway;  X \\<in> synth (analz (knows Spy evsf)) |]
    9.32 -          ==> Says Spy B X  # evsf \\<in> otway"
    9.33 +   Fake: "[| evsf \<in> otway;  X \<in> synth (analz (knows Spy evsf)) |]
    9.34 +          ==> Says Spy B X  # evsf \<in> otway"
    9.35  
    9.36           (*A message that has been sent can be received by the
    9.37             intended recipient.*)
    9.38 -    Reception "[| evsr \\<in> otway;  Says A B X \\<in> set evsr |]
    9.39 -               ==> Gets B X # evsr \\<in> otway"
    9.40 +   Reception: "[| evsr \<in> otway;  Says A B X \<in>set evsr |]
    9.41 +               ==> Gets B X # evsr \<in> otway"
    9.42  
    9.43           (*Alice initiates a protocol run*)
    9.44 -    OR1  "[| evs1 \\<in> otway;  Nonce NA \\<notin> used evs1 |]
    9.45 -          ==> Says A B {|Nonce NA, Agent A, Agent B, 
    9.46 -                         Crypt (shrK A) {|Nonce NA, Agent A, Agent B|} |} 
    9.47 -                 # evs1 \\<in> otway"
    9.48 +   OR1:  "[| evs1 \<in> otway;  Nonce NA \<notin> used evs1 |]
    9.49 +          ==> Says A B {|Nonce NA, Agent A, Agent B,
    9.50 +                         Crypt (shrK A) {|Nonce NA, Agent A, Agent B|} |}
    9.51 +                 # evs1 \<in> otway"
    9.52  
    9.53 -         (*Bob's response to Alice's message. 
    9.54 +         (*Bob's response to Alice's message.
    9.55             This variant of the protocol does NOT encrypt NB.*)
    9.56 -    OR2  "[| evs2 \\<in> otway;  Nonce NB \\<notin> used evs2;
    9.57 -             Gets B {|Nonce NA, Agent A, Agent B, X|} \\<in> set evs2 |]
    9.58 -          ==> Says B Server 
    9.59 +   OR2:  "[| evs2 \<in> otway;  Nonce NB \<notin> used evs2;
    9.60 +             Gets B {|Nonce NA, Agent A, Agent B, X|} \<in> set evs2 |]
    9.61 +          ==> Says B Server
    9.62                    {|Nonce NA, Agent A, Agent B, X, Nonce NB,
    9.63                      Crypt (shrK B) {|Nonce NA, Agent A, Agent B|}|}
    9.64 -                 # evs2 \\<in> otway"
    9.65 +                 # evs2 \<in> otway"
    9.66  
    9.67           (*The Server receives Bob's message and checks that the three NAs
    9.68             match.  Then he sends a new session key to Bob with a packet for
    9.69             forwarding to Alice.*)
    9.70 -    OR3  "[| evs3 \\<in> otway;  Key KAB \\<notin> used evs3;
    9.71 -             Gets Server 
    9.72 -                  {|Nonce NA, Agent A, Agent B, 
    9.73 -                    Crypt (shrK A) {|Nonce NA, Agent A, Agent B|}, 
    9.74 -                    Nonce NB, 
    9.75 +   OR3:  "[| evs3 \<in> otway;  Key KAB \<notin> used evs3;
    9.76 +             Gets Server
    9.77 +                  {|Nonce NA, Agent A, Agent B,
    9.78 +                    Crypt (shrK A) {|Nonce NA, Agent A, Agent B|},
    9.79 +                    Nonce NB,
    9.80                      Crypt (shrK B) {|Nonce NA, Agent A, Agent B|}|}
    9.81 -               \\<in> set evs3 |]
    9.82 -          ==> Says Server B 
    9.83 -                  {|Nonce NA, 
    9.84 +               \<in> set evs3 |]
    9.85 +          ==> Says Server B
    9.86 +                  {|Nonce NA,
    9.87                      Crypt (shrK A) {|Nonce NA, Key KAB|},
    9.88                      Crypt (shrK B) {|Nonce NB, Key KAB|}|}
    9.89 -                 # evs3 \\<in> otway"
    9.90 +                 # evs3 \<in> otway"
    9.91  
    9.92           (*Bob receives the Server's (?) message and compares the Nonces with
    9.93  	   those in the message he previously sent the Server.
    9.94             Need B ~= Server because we allow messages to self.*)
    9.95 -    OR4  "[| evs4 \\<in> otway;  B ~= Server;
    9.96 +   OR4:  "[| evs4 \<in> otway;  B ~= Server;
    9.97               Says B Server {|Nonce NA, Agent A, Agent B, X', Nonce NB,
    9.98                               Crypt (shrK B) {|Nonce NA, Agent A, Agent B|}|}
    9.99 -               \\<in> set evs4;
   9.100 +               \<in> set evs4;
   9.101               Gets B {|Nonce NA, X, Crypt (shrK B) {|Nonce NB, Key K|}|}
   9.102 -               \\<in> set evs4 |]
   9.103 -          ==> Says B A {|Nonce NA, X|} # evs4 \\<in> otway"
   9.104 +               \<in> set evs4 |]
   9.105 +          ==> Says B A {|Nonce NA, X|} # evs4 \<in> otway"
   9.106  
   9.107           (*This message models possible leaks of session keys.  The nonces
   9.108             identify the protocol run.*)
   9.109 -    Oops "[| evso \\<in> otway;  
   9.110 +   Oops: "[| evso \<in> otway;
   9.111               Says Server B {|Nonce NA, X, Crypt (shrK B) {|Nonce NB, Key K|}|}
   9.112 -               \\<in> set evso |]
   9.113 -          ==> Notes Spy {|Nonce NA, Nonce NB, Key K|} # evso \\<in> otway"
   9.114 +               \<in> set evso |]
   9.115 +          ==> Notes Spy {|Nonce NA, Nonce NB, Key K|} # evso \<in> otway"
   9.116 +
   9.117 +
   9.118 +declare Says_imp_knows_Spy [THEN analz.Inj, dest]
   9.119 +declare parts.Body  [dest]
   9.120 +declare analz_into_parts [dest]
   9.121 +declare Fake_parts_insert_in_Un  [dest]
   9.122 +
   9.123 +(*A "possibility property": there are traces that reach the end*)
   9.124 +lemma "B \<noteq> Server
   9.125 +      ==> \<exists>K. \<exists>NA. \<exists>evs \<in> otway.
   9.126 +            Says B A {|Nonce NA, Crypt (shrK A) {|Nonce NA, Key K|}|}
   9.127 +              \<in> set evs"
   9.128 +apply (intro exI bexI)
   9.129 +apply (rule_tac [2] otway.Nil
   9.130 +                    [THEN otway.OR1, THEN otway.Reception,
   9.131 +                     THEN otway.OR2, THEN otway.Reception,
   9.132 +                     THEN otway.OR3, THEN otway.Reception, THEN otway.OR4])
   9.133 +apply possibility
   9.134 +done
   9.135 +
   9.136 +lemma Gets_imp_Says [dest!]:
   9.137 +     "[| Gets B X \<in> set evs; evs \<in> otway |] ==> \<exists>A. Says A B X \<in> set evs"
   9.138 +apply (erule rev_mp)
   9.139 +apply (erule otway.induct)
   9.140 +apply auto
   9.141 +done
   9.142 +
   9.143 +
   9.144 +(**** Inductive proofs about otway ****)
   9.145 +
   9.146 +
   9.147 +(** For reasoning about the encrypted portion of messages **)
   9.148 +
   9.149 +lemma OR2_analz_knows_Spy:
   9.150 +     "[| Gets B {|N, Agent A, Agent B, X|} \<in> set evs;  evs \<in> otway |]
   9.151 +      ==> X \<in> analz (knows Spy evs)"
   9.152 +by blast
   9.153 +
   9.154 +lemma OR4_analz_knows_Spy:
   9.155 +     "[| Gets B {|N, X, Crypt (shrK B) X'|} \<in> set evs;  evs \<in> otway |]
   9.156 +      ==> X \<in> analz (knows Spy evs)"
   9.157 +by blast
   9.158 +
   9.159 +lemma Oops_parts_knows_Spy:
   9.160 +     "Says Server B {|NA, X, Crypt K' {|NB,K|}|} \<in> set evs
   9.161 +      ==> K \<in> parts (knows Spy evs)"
   9.162 +by blast
   9.163 +
   9.164 +(*Forwarding lemma: see comments in OtwayRees.thy*)
   9.165 +lemmas OR2_parts_knows_Spy =
   9.166 +    OR2_analz_knows_Spy [THEN analz_into_parts, standard]
   9.167 +
   9.168 +
   9.169 +(** Theorems of the form X \<notin> parts (knows Spy evs) imply that NOBODY
   9.170 +    sends messages containing X! **)
   9.171 +
   9.172 +(*Spy never sees a good agent's shared key!*)
   9.173 +lemma Spy_see_shrK [simp]:
   9.174 +     "evs \<in> otway ==> (Key (shrK A) \<in> parts (knows Spy evs)) = (A \<in> bad)"
   9.175 +apply (erule otway.induct, force,
   9.176 +       drule_tac [4] OR2_parts_knows_Spy, simp_all)
   9.177 +apply blast+
   9.178 +done
   9.179 +
   9.180 +lemma Spy_analz_shrK [simp]:
   9.181 +     "evs \<in> otway ==> (Key (shrK A) \<in> analz (knows Spy evs)) = (A \<in> bad)"
   9.182 +by auto
   9.183 +
   9.184 +lemma Spy_see_shrK_D [dest!]:
   9.185 +     "[|Key (shrK A) \<in> parts (knows Spy evs);  evs \<in> otway|] ==> A \<in> bad"
   9.186 +by (blast dest: Spy_see_shrK)
   9.187 +
   9.188 +
   9.189 +(*** Proofs involving analz ***)
   9.190 +
   9.191 +(*Describes the form of K and NA when the Server sends this message.  Also
   9.192 +  for Oops case.*)
   9.193 +lemma Says_Server_message_form:
   9.194 +     "[| Says Server B {|NA, X, Crypt (shrK B) {|NB, Key K|}|} \<in> set evs;
   9.195 +         evs \<in> otway |]
   9.196 +      ==> K \<notin> range shrK & (\<exists>i. NA = Nonce i) & (\<exists>j. NB = Nonce j)"
   9.197 +apply (erule rev_mp)
   9.198 +apply (erule otway.induct, simp_all)
   9.199 +apply blast
   9.200 +done
   9.201 +
   9.202 +
   9.203 +(****
   9.204 + The following is to prove theorems of the form
   9.205 +
   9.206 +  Key K \<in> analz (insert (Key KAB) (knows Spy evs)) ==>
   9.207 +  Key K \<in> analz (knows Spy evs)
   9.208 +
   9.209 + A more general formula must be proved inductively.
   9.210 +****)
   9.211 +
   9.212 +
   9.213 +(** Session keys are not used to encrypt other session keys **)
   9.214 +
   9.215 +(*The equality makes the induction hypothesis easier to apply*)
   9.216 +lemma analz_image_freshK [rule_format]:
   9.217 + "evs \<in> otway ==>
   9.218 +   \<forall>K KK. KK <= -(range shrK) -->
   9.219 +          (Key K \<in> analz (Key`KK Un (knows Spy evs))) =
   9.220 +          (K \<in> KK | Key K \<in> analz (knows Spy evs))"
   9.221 +apply (erule otway.induct, force)
   9.222 +apply (frule_tac [7] Says_Server_message_form)
   9.223 +apply (drule_tac [6] OR4_analz_knows_Spy)
   9.224 +apply (drule_tac [4] OR2_analz_knows_Spy)
   9.225 +apply analz_freshK
   9.226 +apply spy_analz
   9.227 +done
   9.228 +
   9.229 +lemma analz_insert_freshK:
   9.230 +  "[| evs \<in> otway;  KAB \<notin> range shrK |] ==>
   9.231 +      Key K \<in> analz (insert (Key KAB) (knows Spy evs)) =
   9.232 +      (K = KAB | Key K \<in> analz (knows Spy evs))"
   9.233 +by (simp only: analz_image_freshK analz_image_freshK_simps)
   9.234 +
   9.235 +
   9.236 +(*** The Key K uniquely identifies the Server's  message. **)
   9.237 +
   9.238 +lemma unique_session_keys:
   9.239 +     "[| Says Server B {|NA, X, Crypt (shrK B) {|NB, K|}|}   \<in> set evs;
   9.240 +         Says Server B' {|NA',X',Crypt (shrK B') {|NB',K|}|} \<in> set evs;
   9.241 +         evs \<in> otway |] ==> X=X' & B=B' & NA=NA' & NB=NB'"
   9.242 +apply (erule rev_mp)
   9.243 +apply (erule rev_mp)
   9.244 +apply (erule otway.induct, simp_all)
   9.245 +(*Remaining cases: OR3 and OR4*)
   9.246 +apply blast+
   9.247 +done
   9.248 +
   9.249 +
   9.250 +(** Crucial secrecy property: Spy does not see the keys sent in msg OR3
   9.251 +    Does not in itself guarantee security: an attack could violate
   9.252 +    the premises, e.g. by having A=Spy **)
   9.253 +
   9.254 +lemma secrecy_lemma:
   9.255 + "[| A \<notin> bad;  B \<notin> bad;  evs \<in> otway |]
   9.256 +  ==> Says Server B
   9.257 +        {|NA, Crypt (shrK A) {|NA, Key K|},
   9.258 +          Crypt (shrK B) {|NB, Key K|}|} \<in> set evs -->
   9.259 +      Notes Spy {|NA, NB, Key K|} \<notin> set evs -->
   9.260 +      Key K \<notin> analz (knows Spy evs)"
   9.261 +apply (erule otway.induct, force)
   9.262 +apply (frule_tac [7] Says_Server_message_form)
   9.263 +apply (drule_tac [6] OR4_analz_knows_Spy)
   9.264 +apply (drule_tac [4] OR2_analz_knows_Spy)
   9.265 +apply (simp_all add: analz_insert_eq analz_insert_freshK pushes)
   9.266 +apply spy_analz  (*Fake*)
   9.267 +(*OR3, OR4, Oops*)
   9.268 +apply (blast dest: unique_session_keys)+
   9.269 +done
   9.270 +
   9.271 +
   9.272 +lemma Spy_not_see_encrypted_key:
   9.273 +     "[| Says Server B
   9.274 +          {|NA, Crypt (shrK A) {|NA, Key K|},
   9.275 +                Crypt (shrK B) {|NB, Key K|}|} \<in> set evs;
   9.276 +         Notes Spy {|NA, NB, Key K|} \<notin> set evs;
   9.277 +         A \<notin> bad;  B \<notin> bad;  evs \<in> otway |]
   9.278 +      ==> Key K \<notin> analz (knows Spy evs)"
   9.279 +by (blast dest: Says_Server_message_form secrecy_lemma)
   9.280 +
   9.281 +
   9.282 +(*** Attempting to prove stronger properties ***)
   9.283 +
   9.284 +(*Only OR1 can have caused such a part of a message to appear.
   9.285 +  The premise A \<noteq> B prevents OR2's similar-looking cryptogram from being
   9.286 +  picked up.  Original Otway-Rees doesn't need it.*)
   9.287 +lemma Crypt_imp_OR1 [rule_format]:
   9.288 +     "[| A \<notin> bad;  A \<noteq> B;  evs \<in> otway |]
   9.289 +      ==> Crypt (shrK A) {|NA, Agent A, Agent B|} \<in> parts (knows Spy evs) -->
   9.290 +          Says A B {|NA, Agent A, Agent B,
   9.291 +                     Crypt (shrK A) {|NA, Agent A, Agent B|}|}  \<in> set evs"
   9.292 +apply (erule otway.induct, force,
   9.293 +       drule_tac [4] OR2_parts_knows_Spy, simp_all)
   9.294 +apply blast+
   9.295 +done
   9.296 +
   9.297 +
   9.298 +(*Crucial property: If the encrypted message appears, and A has used NA
   9.299 +  to start a run, then it originated with the Server!
   9.300 +  The premise A \<noteq> B allows use of Crypt_imp_OR1*)
   9.301 +(*Only it is FALSE.  Somebody could make a fake message to Server
   9.302 +          substituting some other nonce NA' for NB.*)
   9.303 +lemma "[| A \<notin> bad;  A \<noteq> B;  evs \<in> otway |]
   9.304 +       ==> Crypt (shrK A) {|NA, Key K|} \<in> parts (knows Spy evs) -->
   9.305 +           Says A B {|NA, Agent A, Agent B,
   9.306 +                      Crypt (shrK A) {|NA, Agent A, Agent B|}|}
   9.307 +            \<in> set evs -->
   9.308 +           (\<exists>B NB. Says Server B
   9.309 +                {|NA,
   9.310 +                  Crypt (shrK A) {|NA, Key K|},
   9.311 +                  Crypt (shrK B) {|NB, Key K|}|}  \<in> set evs)"
   9.312 +apply (erule otway.induct, force,
   9.313 +       drule_tac [4] OR2_parts_knows_Spy)
   9.314 +apply simp_all
   9.315 +(*Fake*)
   9.316 +apply blast
   9.317 +(*OR1: it cannot be a new Nonce, contradiction.*)
   9.318 +apply blast
   9.319 +(*OR3 and OR4*)
   9.320 +apply (simp_all add: ex_disj_distrib)
   9.321 +(*OR4*)
   9.322 +prefer 2 apply (blast intro!: Crypt_imp_OR1)
   9.323 +(*OR3*)
   9.324 +apply clarify
   9.325 +(*The hypotheses at this point suggest an attack in which nonce NB is used
   9.326 +  in two different roles:
   9.327 +          Gets Server
   9.328 +           {|Nonce NA, Agent Aa, Agent A,
   9.329 +             Crypt (shrK Aa) {|Nonce NA, Agent Aa, Agent A|}, Nonce NB,
   9.330 +             Crypt (shrK A) {|Nonce NA, Agent Aa, Agent A|}|}
   9.331 +          \<in> set evs3
   9.332 +          Says A B
   9.333 +           {|Nonce NB, Agent A, Agent B,
   9.334 +             Crypt (shrK A) {|Nonce NB, Agent A, Agent B|}|}
   9.335 +          \<in> set evs3;
   9.336 +*)
   9.337 +
   9.338 +
   9.339 +(*Thus the key property A_can_trust probably fails too.*)
   9.340 +oops
   9.341  
   9.342  end
    10.1 --- a/src/HOL/Auth/WooLam.ML	Wed Apr 11 11:53:54 2001 +0200
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,142 +0,0 @@
    10.4 -(*  Title:      HOL/Auth/WooLam
    10.5 -    ID:         $Id$
    10.6 -    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
    10.7 -    Copyright   1996  University of Cambridge
    10.8 -
    10.9 -Inductive relation "woolam" for the Woo-Lam protocol.
   10.10 -
   10.11 -Simplified version from page 11 of
   10.12 -  Abadi and Needham.  Prudent Engineering Practice for Cryptographic Protocols.
   10.13 -  IEEE Trans. S.E. 22(1), 1996, pages 6-15.
   10.14 -*)
   10.15 -
   10.16 -AddDs  [Says_imp_knows_Spy RS parts.Inj, parts.Body];
   10.17 -AddDs  [impOfSubs analz_subset_parts, impOfSubs Fake_parts_insert];
   10.18 -
   10.19 -
   10.20 -(*A "possibility property": there are traces that reach the end*)
   10.21 -Goal "\\<exists>NB. \\<exists>evs \\<in> woolam.  \
   10.22 -\           Says Server B (Crypt (shrK B) {|Agent A, Nonce NB|}) \\<in> set evs";
   10.23 -by (REPEAT (resolve_tac [exI,bexI] 1));
   10.24 -by (rtac (woolam.Nil RS woolam.WL1 RS woolam.WL2 RS woolam.WL3 RS 
   10.25 -          woolam.WL4 RS woolam.WL5) 2);
   10.26 -by possibility_tac;
   10.27 -result();
   10.28 -
   10.29 -
   10.30 -(**** Inductive proofs about woolam ****)
   10.31 -
   10.32 -(** For reasoning about the encrypted portion of messages **)
   10.33 -
   10.34 -Goal "Says A' B X \\<in> set evs ==> X \\<in> analz (spies evs)";
   10.35 -by (etac (Says_imp_spies RS analz.Inj) 1);
   10.36 -qed "WL4_analz_spies";
   10.37 -
   10.38 -bind_thm ("WL4_parts_spies",
   10.39 -          WL4_analz_spies RS (impOfSubs analz_subset_parts));
   10.40 -
   10.41 -(*For proving the easier theorems about X \\<notin> parts (spies evs) *)
   10.42 -fun parts_induct_tac i = 
   10.43 -    etac woolam.induct i  THEN 
   10.44 -    ftac WL4_parts_spies (i+5)  THEN
   10.45 -    prove_simple_subgoals_tac 1;
   10.46 -
   10.47 -
   10.48 -(** Theorems of the form X \\<notin> parts (spies evs) imply that NOBODY
   10.49 -    sends messages containing X! **)
   10.50 -
   10.51 -(*Spy never sees another agent's shared key! (unless it's bad at start)*)
   10.52 -Goal "evs \\<in> woolam ==> (Key (shrK A) \\<in> parts (spies evs)) = (A \\<in> bad)";
   10.53 -by (parts_induct_tac 1);
   10.54 -by (Blast_tac 1);
   10.55 -qed "Spy_see_shrK";
   10.56 -Addsimps [Spy_see_shrK];
   10.57 -
   10.58 -Goal "evs \\<in> woolam ==> (Key (shrK A) \\<in> analz (spies evs)) = (A \\<in> bad)";
   10.59 -by Auto_tac;
   10.60 -qed "Spy_analz_shrK";
   10.61 -Addsimps [Spy_analz_shrK];
   10.62 -
   10.63 -AddSDs [Spy_see_shrK RSN (2, rev_iffD1), 
   10.64 -	Spy_analz_shrK RSN (2, rev_iffD1)];
   10.65 -
   10.66 -
   10.67 -(**** Autheticity properties for Woo-Lam ****)
   10.68 -
   10.69 -
   10.70 -(*** WL4 ***)
   10.71 -
   10.72 -(*If the encrypted message appears then it originated with Alice*)
   10.73 -Goal "[| Crypt (shrK A) (Nonce NB) \\<in> parts (spies evs);  \
   10.74 -\        A \\<notin> bad;  evs \\<in> woolam |]                      \
   10.75 -\     ==> \\<exists>B. Says A B (Crypt (shrK A) (Nonce NB)) \\<in> set evs";
   10.76 -by (etac rev_mp 1);
   10.77 -by (parts_induct_tac 1);
   10.78 -by (ALLGOALS Blast_tac);
   10.79 -qed "NB_Crypt_imp_Alice_msg";
   10.80 -
   10.81 -(*Guarantee for Server: if it gets a message containing a certificate from 
   10.82 -  Alice, then she originated that certificate.  But we DO NOT know that B
   10.83 -  ever saw it: the Spy may have rerouted the message to the Server.*)
   10.84 -Goal "[| Says B' Server {|Agent A, Agent B, Crypt (shrK A) (Nonce NB)|} \
   10.85 -\          \\<in> set evs;                                                   \
   10.86 -\        A \\<notin> bad;  evs \\<in> woolam |]                                     \
   10.87 -\     ==> \\<exists>B. Says A B (Crypt (shrK A) (Nonce NB)) \\<in> set evs";
   10.88 -by (blast_tac (claset() addSIs [NB_Crypt_imp_Alice_msg]) 1);
   10.89 -qed "Server_trusts_WL4";
   10.90 -
   10.91 -AddDs [Server_trusts_WL4];
   10.92 -
   10.93 -
   10.94 -(*** WL5 ***)
   10.95 -
   10.96 -(*Server sent WL5 only if it received the right sort of message*)
   10.97 -Goal "[| Says Server B (Crypt (shrK B) {|Agent A, NB|}) \\<in> set evs;      \
   10.98 -\        evs \\<in> woolam |]                                                \
   10.99 -\     ==> \\<exists>B'. Says B' Server {|Agent A, Agent B, Crypt (shrK A) NB|} \
  10.100 -\            \\<in> set evs";
  10.101 -by (etac rev_mp 1);
  10.102 -by (parts_induct_tac 1);
  10.103 -by (ALLGOALS Blast_tac);
  10.104 -qed "Server_sent_WL5";
  10.105 -
  10.106 -AddDs [Server_sent_WL5];
  10.107 -
  10.108 -(*If the encrypted message appears then it originated with the Server!*)
  10.109 -Goal "[| Crypt (shrK B) {|Agent A, NB|} \\<in> parts (spies evs);  \
  10.110 -\        B \\<notin> bad;  evs \\<in> woolam |]                           \
  10.111 -\     ==> Says Server B (Crypt (shrK B) {|Agent A, NB|}) \\<in> set evs";
  10.112 -by (etac rev_mp 1);
  10.113 -by (parts_induct_tac 1);
  10.114 -by (Blast_tac 1);
  10.115 -qed_spec_mp "NB_Crypt_imp_Server_msg";
  10.116 -
  10.117 -(*Guarantee for B.  If B gets the Server's certificate then A has encrypted
  10.118 -  the nonce using her key.  This event can be no older than the nonce itself.
  10.119 -  But A may have sent the nonce to some other agent and it could have reached
  10.120 -  the Server via the Spy.*)
  10.121 -Goal "[| Says S B (Crypt (shrK B) {|Agent A, Nonce NB|}): set evs; \
  10.122 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> woolam  |]                  \
  10.123 -\     ==> \\<exists>B. Says A B (Crypt (shrK A) (Nonce NB)) \\<in> set evs";
  10.124 -by (blast_tac (claset() addSDs [NB_Crypt_imp_Server_msg]) 1);
  10.125 -qed "B_trusts_WL5";
  10.126 -
  10.127 -
  10.128 -(*B only issues challenges in response to WL1.  Not used.*)
  10.129 -Goal "[| Says B A (Nonce NB) \\<in> set evs;  B \\<noteq> Spy;  evs \\<in> woolam |]  \
  10.130 -\     ==> \\<exists>A'. Says A' B (Agent A) \\<in> set evs";
  10.131 -by (etac rev_mp 1);
  10.132 -by (parts_induct_tac 1);
  10.133 -by (ALLGOALS Blast_tac);
  10.134 -qed "B_said_WL2";
  10.135 -
  10.136 -
  10.137 -(**CANNOT be proved because A doesn't know where challenges come from...
  10.138 -Goal "[| A \\<notin> bad;  B \\<noteq> Spy;  evs \\<in> woolam |]           \
  10.139 -\ ==> Crypt (shrK A) (Nonce NB) \\<in> parts (spies evs) &  \
  10.140 -\     Says B A (Nonce NB) \\<in> set evs                       \
  10.141 -\     --> Says A B (Crypt (shrK A) (Nonce NB)) \\<in> set evs";
  10.142 -by (parts_induct_tac 1);
  10.143 -by (Blast_tac 1);
  10.144 -by Safe_tac;
  10.145 -**)
    11.1 --- a/src/HOL/Auth/WooLam.thy	Wed Apr 11 11:53:54 2001 +0200
    11.2 +++ b/src/HOL/Auth/WooLam.thy	Thu Apr 12 12:45:05 2001 +0200
    11.3 @@ -14,52 +14,166 @@
    11.4    Computer Security Foundations Workshop, 1996.
    11.5  *)
    11.6  
    11.7 -WooLam = Shared + 
    11.8 +theory WooLam = Shared:
    11.9  
   11.10 -consts  woolam  :: event list set
   11.11 +consts  woolam  :: "event list set"
   11.12  inductive woolam
   11.13 -  intrs 
   11.14 +  intros
   11.15           (*Initial trace is empty*)
   11.16 -    Nil  "[] \\<in> woolam"
   11.17 +   Nil:  "[] \<in> woolam"
   11.18  
   11.19           (** These rules allow agents to send messages to themselves **)
   11.20  
   11.21           (*The spy MAY say anything he CAN say.  We do not expect him to
   11.22             invent new nonces here, but he can also use NS1.  Common to
   11.23             all similar protocols.*)
   11.24 -    Fake "[| evsf \\<in> woolam;  X \\<in> synth (analz (spies evsf)) |]
   11.25 -          ==> Says Spy B X  # evsf \\<in> woolam"
   11.26 +   Fake: "[| evsf \<in> woolam;  X \<in> synth (analz (spies evsf)) |]
   11.27 +          ==> Says Spy B X  # evsf \<in> woolam"
   11.28  
   11.29           (*Alice initiates a protocol run*)
   11.30 -    WL1  "[| evs1 \\<in> woolam |]
   11.31 -          ==> Says A B (Agent A) # evs1 \\<in> woolam"
   11.32 +   WL1:  "evs1 \<in> woolam ==> Says A B (Agent A) # evs1 \<in> woolam"
   11.33  
   11.34           (*Bob responds to Alice's message with a challenge.*)
   11.35 -    WL2  "[| evs2 \\<in> woolam;  Says A' B (Agent A) \\<in> set evs2 |]
   11.36 -          ==> Says B A (Nonce NB) # evs2 \\<in> woolam"
   11.37 +   WL2:  "[| evs2 \<in> woolam;  Says A' B (Agent A) \<in> set evs2 |]
   11.38 +          ==> Says B A (Nonce NB) # evs2 \<in> woolam"
   11.39  
   11.40           (*Alice responds to Bob's challenge by encrypting NB with her key.
   11.41             B is *not* properly determined -- Alice essentially broadcasts
   11.42             her reply.*)
   11.43 -    WL3  "[| evs3 \\<in> woolam;
   11.44 -             Says A  B (Agent A)  \\<in> set evs3;
   11.45 -             Says B' A (Nonce NB) \\<in> set evs3 |]
   11.46 -          ==> Says A B (Crypt (shrK A) (Nonce NB)) # evs3 \\<in> woolam"
   11.47 +   WL3:  "[| evs3 \<in> woolam;
   11.48 +             Says A  B (Agent A)  \<in> set evs3;
   11.49 +             Says B' A (Nonce NB) \<in> set evs3 |]
   11.50 +          ==> Says A B (Crypt (shrK A) (Nonce NB)) # evs3 \<in> woolam"
   11.51  
   11.52           (*Bob forwards Alice's response to the Server.  NOTE: usually
   11.53             the messages are shown in chronological order, for clarity.
   11.54             But here, exchanging the two events would cause the lemma
   11.55             WL4_analz_spies to pick up the wrong assumption!*)
   11.56 -    WL4  "[| evs4 \\<in> woolam;  
   11.57 -             Says A'  B X         \\<in> set evs4;
   11.58 -             Says A'' B (Agent A) \\<in> set evs4 |]
   11.59 -          ==> Says B Server {|Agent A, Agent B, X|} # evs4 \\<in> woolam"
   11.60 +   WL4:  "[| evs4 \<in> woolam;
   11.61 +             Says A'  B X         \<in> set evs4;
   11.62 +             Says A'' B (Agent A) \<in> set evs4 |]
   11.63 +          ==> Says B Server {|Agent A, Agent B, X|} # evs4 \<in> woolam"
   11.64  
   11.65           (*Server decrypts Alice's response for Bob.*)
   11.66 -    WL5  "[| evs5 \\<in> woolam;  
   11.67 +   WL5:  "[| evs5 \<in> woolam;
   11.68               Says B' Server {|Agent A, Agent B, Crypt (shrK A) (Nonce NB)|}
   11.69 -               \\<in> set evs5 |]
   11.70 +               \<in> set evs5 |]
   11.71            ==> Says Server B (Crypt (shrK B) {|Agent A, Nonce NB|})
   11.72 -                 # evs5 \\<in> woolam"
   11.73 +                 # evs5 \<in> woolam"
   11.74 +
   11.75 +
   11.76 +declare Says_imp_knows_Spy [THEN analz.Inj, dest]
   11.77 +declare parts.Body  [dest]
   11.78 +declare analz_into_parts [dest]
   11.79 +declare Fake_parts_insert_in_Un  [dest]
   11.80 +
   11.81 +
   11.82 +(*A "possibility property": there are traces that reach the end*)
   11.83 +lemma "\<exists>NB. \<exists>evs \<in> woolam.
   11.84 +             Says Server B (Crypt (shrK B) {|Agent A, Nonce NB|}) \<in> set evs"
   11.85 +apply (intro exI bexI)
   11.86 +apply (rule_tac [2] woolam.Nil
   11.87 +                    [THEN woolam.WL1, THEN woolam.WL2, THEN woolam.WL3,
   11.88 +                     THEN woolam.WL4, THEN woolam.WL5])
   11.89 +apply possibility
   11.90 +done
   11.91 +
   11.92 +(*Could prove forwarding lemmas for WL4, but we do not need them!*)
   11.93 +
   11.94 +(**** Inductive proofs about woolam ****)
   11.95 +
   11.96 +(** Theorems of the form X \<notin> parts (spies evs) imply that NOBODY
   11.97 +    sends messages containing X! **)
   11.98 +
   11.99 +(*Spy never sees a good agent's shared key!*)
  11.100 +lemma Spy_see_shrK [simp]:
  11.101 +     "evs \<in> woolam ==> (Key (shrK A) \<in> parts (spies evs)) = (A \<in> bad)"
  11.102 +apply (erule woolam.induct, force, simp_all)
  11.103 +apply blast+
  11.104 +done
  11.105 +
  11.106 +lemma Spy_analz_shrK [simp]:
  11.107 +     "evs \<in> woolam ==> (Key (shrK A) \<in> analz (spies evs)) = (A \<in> bad)"
  11.108 +by auto
  11.109 +
  11.110 +lemma Spy_see_shrK_D [dest!]:
  11.111 +     "[|Key (shrK A) \<in> parts (knows Spy evs);  evs \<in> woolam|] ==> A \<in> bad"
  11.112 +by (blast dest: Spy_see_shrK)
  11.113 +
  11.114 +
  11.115 +(**** Autheticity properties for Woo-Lam ****)
  11.116 +
  11.117 +(*** WL4 ***)
  11.118 +
  11.119 +(*If the encrypted message appears then it originated with Alice*)
  11.120 +lemma NB_Crypt_imp_Alice_msg:
  11.121 +     "[| Crypt (shrK A) (Nonce NB) \<in> parts (spies evs);
  11.122 +         A \<notin> bad;  evs \<in> woolam |]
  11.123 +      ==> \<exists>B. Says A B (Crypt (shrK A) (Nonce NB)) \<in> set evs"
  11.124 +apply (erule rev_mp, erule woolam.induct, force, simp_all)
  11.125 +apply blast+
  11.126 +done
  11.127 +
  11.128 +(*Guarantee for Server: if it gets a message containing a certificate from
  11.129 +  Alice, then she originated that certificate.  But we DO NOT know that B
  11.130 +  ever saw it: the Spy may have rerouted the message to the Server.*)
  11.131 +lemma Server_trusts_WL4 [dest]:
  11.132 +     "[| Says B' Server {|Agent A, Agent B, Crypt (shrK A) (Nonce NB)|}
  11.133 +           \<in> set evs;
  11.134 +         A \<notin> bad;  evs \<in> woolam |]
  11.135 +      ==> \<exists>B. Says A B (Crypt (shrK A) (Nonce NB)) \<in> set evs"
  11.136 +by (blast intro!: NB_Crypt_imp_Alice_msg)
  11.137 +
  11.138 +
  11.139 +(*** WL5 ***)
  11.140 +
  11.141 +(*Server sent WL5 only if it received the right sort of message*)
  11.142 +lemma Server_sent_WL5 [dest]:
  11.143 +     "[| Says Server B (Crypt (shrK B) {|Agent A, NB|}) \<in> set evs;
  11.144 +         evs \<in> woolam |]
  11.145 +      ==> \<exists>B'. Says B' Server {|Agent A, Agent B, Crypt (shrK A) NB|}
  11.146 +             \<in> set evs"
  11.147 +apply (erule rev_mp, erule woolam.induct, force, simp_all)
  11.148 +apply blast+
  11.149 +done
  11.150 +
  11.151 +(*If the encrypted message appears then it originated with the Server!*)
  11.152 +lemma NB_Crypt_imp_Server_msg [rule_format]:
  11.153 +     "[| Crypt (shrK B) {|Agent A, NB|} \<in> parts (spies evs);
  11.154 +         B \<notin> bad;  evs \<in> woolam |]
  11.155 +      ==> Says Server B (Crypt (shrK B) {|Agent A, NB|}) \<in> set evs"
  11.156 +apply (erule rev_mp, erule woolam.induct, force, simp_all)
  11.157 +apply blast+
  11.158 +done
  11.159 +
  11.160 +(*Guarantee for B.  If B gets the Server's certificate then A has encrypted
  11.161 +  the nonce using her key.  This event can be no older than the nonce itself.
  11.162 +  But A may have sent the nonce to some other agent and it could have reached
  11.163 +  the Server via the Spy.*)
  11.164 +lemma B_trusts_WL5:
  11.165 +     "[| Says S B (Crypt (shrK B) {|Agent A, Nonce NB|}): set evs;
  11.166 +         A \<notin> bad;  B \<notin> bad;  evs \<in> woolam  |]
  11.167 +      ==> \<exists>B. Says A B (Crypt (shrK A) (Nonce NB)) \<in> set evs"
  11.168 +by (blast dest!: NB_Crypt_imp_Server_msg)
  11.169 +
  11.170 +
  11.171 +(*B only issues challenges in response to WL1.  Not used.*)
  11.172 +lemma B_said_WL2:
  11.173 +     "[| Says B A (Nonce NB) \<in> set evs;  B \<noteq> Spy;  evs \<in> woolam |]
  11.174 +      ==> \<exists>A'. Says A' B (Agent A) \<in> set evs"
  11.175 +apply (erule rev_mp, erule woolam.induct, force, simp_all)
  11.176 +apply blast+
  11.177 +done
  11.178 +
  11.179 +
  11.180 +(**CANNOT be proved because A doesn't know where challenges come from...*)
  11.181 +lemma "[| A \<notin> bad;  B \<noteq> Spy;  evs \<in> woolam |]
  11.182 +  ==> Crypt (shrK A) (Nonce NB) \<in> parts (spies evs) &
  11.183 +      Says B A (Nonce NB) \<in> set evs
  11.184 +      --> Says A B (Crypt (shrK A) (Nonce NB)) \<in> set evs"
  11.185 +apply (erule rev_mp, erule woolam.induct, force, simp_all)
  11.186 +apply blast
  11.187 +apply auto
  11.188 +oops
  11.189  
  11.190  end
    12.1 --- a/src/HOL/Auth/Yahalom.ML	Wed Apr 11 11:53:54 2001 +0200
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,626 +0,0 @@
    12.4 -(*  Title:      HOL/Auth/Yahalom
    12.5 -    ID:         $Id$
    12.6 -    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
    12.7 -    Copyright   1996  University of Cambridge
    12.8 -
    12.9 -Inductive relation "yahalom" for the Yahalom protocol.
   12.10 -
   12.11 -From page 257 of
   12.12 -  Burrows, Abadi and Needham.  A Logic of Authentication.
   12.13 -  Proc. Royal Soc. 426 (1989)
   12.14 -*)
   12.15 -
   12.16 -Pretty.setdepth 25;
   12.17 -
   12.18 -
   12.19 -(*A "possibility property": there are traces that reach the end*)
   12.20 -Goal "A \\<noteq> Server \
   12.21 -\     ==> \\<exists>X NB K. \\<exists>evs \\<in> yahalom.          \
   12.22 -\            Says A B {|X, Crypt K (Nonce NB)|} \\<in> set evs";
   12.23 -by (REPEAT (resolve_tac [exI,bexI] 1));
   12.24 -by (rtac (yahalom.Nil RS 
   12.25 -          yahalom.YM1 RS yahalom.Reception RS
   12.26 -          yahalom.YM2 RS yahalom.Reception RS 
   12.27 -          yahalom.YM3 RS yahalom.Reception RS yahalom.YM4) 2);
   12.28 -by possibility_tac;
   12.29 -result();
   12.30 -
   12.31 -Goal "[| Gets B X \\<in> set evs; evs \\<in> yahalom |] ==> \\<exists>A. Says A B X \\<in> set evs";
   12.32 -by (etac rev_mp 1);
   12.33 -by (etac yahalom.induct 1);
   12.34 -by Auto_tac;
   12.35 -qed "Gets_imp_Says";
   12.36 -
   12.37 -(*Must be proved separately for each protocol*)
   12.38 -Goal "[| Gets B X \\<in> set evs; evs \\<in> yahalom |]  ==> X \\<in> knows Spy evs";
   12.39 -by (blast_tac (claset() addSDs [Gets_imp_Says, Says_imp_knows_Spy]) 1);
   12.40 -qed"Gets_imp_knows_Spy";
   12.41 -AddDs [Gets_imp_knows_Spy RS parts.Inj];
   12.42 -
   12.43 -
   12.44 -(**** Inductive proofs about yahalom ****)
   12.45 -
   12.46 -
   12.47 -(** For reasoning about the encrypted portion of messages **)
   12.48 -
   12.49 -(*Lets us treat YM4 using a similar argument as for the Fake case.*)
   12.50 -Goal "[| Gets A {|Crypt (shrK A) Y, X|} \\<in> set evs;  evs \\<in> yahalom |]  \
   12.51 -\     ==> X \\<in> analz (knows Spy evs)";
   12.52 -by (blast_tac (claset() addSDs [Gets_imp_knows_Spy RS analz.Inj]) 1);
   12.53 -qed "YM4_analz_knows_Spy";
   12.54 -
   12.55 -bind_thm ("YM4_parts_knows_Spy",
   12.56 -          YM4_analz_knows_Spy RS (impOfSubs analz_subset_parts));
   12.57 -
   12.58 -(*For Oops*)
   12.59 -Goal "Says Server A {|Crypt (shrK A) {|B,K,NA,NB|}, X|} \\<in> set evs \
   12.60 -\     ==> K \\<in> parts (knows Spy evs)";
   12.61 -by (blast_tac (claset() addSDs [parts.Body, 
   12.62 -                  Says_imp_knows_Spy RS parts.Inj]) 1);
   12.63 -qed "YM4_Key_parts_knows_Spy";
   12.64 -
   12.65 -(*For proving the easier theorems about X \\<notin> parts (knows Spy evs).*)
   12.66 -fun parts_knows_Spy_tac i = 
   12.67 -  EVERY
   12.68 -   [ftac YM4_Key_parts_knows_Spy (i+7),
   12.69 -    ftac YM4_parts_knows_Spy (i+6), assume_tac (i+6),
   12.70 -    prove_simple_subgoals_tac i];
   12.71 -
   12.72 -(*Induction for regularity theorems.  If induction formula has the form
   12.73 -   X \\<notin> analz (knows Spy evs) --> ... then it shortens the proof by discarding
   12.74 -   needless information about analz (insert X (knows Spy evs))  *)
   12.75 -fun parts_induct_tac i = 
   12.76 -    etac yahalom.induct i
   12.77 -    THEN 
   12.78 -    REPEAT (FIRSTGOAL analz_mono_contra_tac)
   12.79 -    THEN  parts_knows_Spy_tac i;
   12.80 -
   12.81 -
   12.82 -(** Theorems of the form X \\<notin> parts (knows Spy evs) imply that NOBODY
   12.83 -    sends messages containing X! **)
   12.84 -
   12.85 -(*Spy never sees another agent's shared key! (unless it's bad at start)*)
   12.86 -Goal "evs \\<in> yahalom ==> (Key (shrK A) \\<in> parts (knows Spy evs)) = (A \\<in> bad)";
   12.87 -by (parts_induct_tac 1);
   12.88 -by (Fake_parts_insert_tac 1);
   12.89 -by (ALLGOALS Blast_tac);
   12.90 -qed "Spy_see_shrK";
   12.91 -Addsimps [Spy_see_shrK];
   12.92 -
   12.93 -Goal "evs \\<in> yahalom ==> (Key (shrK A) \\<in> analz (knows Spy evs)) = (A \\<in> bad)";
   12.94 -by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset()));
   12.95 -qed "Spy_analz_shrK";
   12.96 -Addsimps [Spy_analz_shrK];
   12.97 -
   12.98 -AddSDs [Spy_see_shrK RSN (2, rev_iffD1), 
   12.99 -	Spy_analz_shrK RSN (2, rev_iffD1)];
  12.100 -
  12.101 -
  12.102 -(*Nobody can have used non-existent keys!  Needed to apply analz_insert_Key*)
  12.103 -Goal "evs \\<in> yahalom ==>          \
  12.104 -\      Key K \\<notin> used evs --> K \\<notin> keysFor (parts (knows Spy evs))";
  12.105 -by (parts_induct_tac 1);
  12.106 -(*Fake*)
  12.107 -by (blast_tac (claset() addSDs [keysFor_parts_insert]) 1);
  12.108 -(*YM2-4: Because Key K is not fresh, etc.*)
  12.109 -by (REPEAT (blast_tac (claset() addSEs knows_Spy_partsEs) 1));
  12.110 -qed_spec_mp "new_keys_not_used";
  12.111 -Addsimps [new_keys_not_used];
  12.112 -
  12.113 -(*Earlier, all protocol proofs declared this theorem.  
  12.114 -  But few of them actually need it! (Another is Kerberos IV) *)
  12.115 -bind_thm ("new_keys_not_analzd",
  12.116 -          [analz_subset_parts RS keysFor_mono,
  12.117 -           new_keys_not_used] MRS contra_subsetD);
  12.118 -
  12.119 -
  12.120 -(*Describes the form of K when the Server sends this message.  Useful for
  12.121 -  Oops as well as main secrecy property.*)
  12.122 -Goal "[| Says Server A {|Crypt (shrK A) {|Agent B, Key K, na, nb|}, X|} \
  12.123 -\          \\<in> set evs;   evs \\<in> yahalom |]                                \
  12.124 -\     ==> K \\<notin> range shrK";
  12.125 -by (etac rev_mp 1);
  12.126 -by (etac yahalom.induct 1);
  12.127 -by (ALLGOALS Asm_simp_tac);
  12.128 -by (Blast_tac 1);
  12.129 -qed "Says_Server_not_range";
  12.130 -
  12.131 -Addsimps [Says_Server_not_range];
  12.132 -
  12.133 -
  12.134 -(*For proofs involving analz.*)
  12.135 -val analz_knows_Spy_tac = 
  12.136 -    ftac YM4_analz_knows_Spy 7 THEN assume_tac 7;
  12.137 -
  12.138 -(****
  12.139 - The following is to prove theorems of the form
  12.140 -
  12.141 -  Key K \\<in> analz (insert (Key KAB) (knows Spy evs)) ==>
  12.142 -  Key K \\<in> analz (knows Spy evs)
  12.143 -
  12.144 - A more general formula must be proved inductively.
  12.145 -****)
  12.146 -
  12.147 -(** Session keys are not used to encrypt other session keys **)
  12.148 -
  12.149 -Goal "evs \\<in> yahalom ==>                              \
  12.150 -\  \\<forall>K KK. KK <= - (range shrK) -->                \
  12.151 -\         (Key K \\<in> analz (Key`KK Un (knows Spy evs))) = \
  12.152 -\         (K \\<in> KK | Key K \\<in> analz (knows Spy evs))";
  12.153 -by (etac yahalom.induct 1);
  12.154 -by analz_knows_Spy_tac;
  12.155 -by (REPEAT_FIRST (resolve_tac [allI, impI]));
  12.156 -by (REPEAT_FIRST (rtac analz_image_freshK_lemma));
  12.157 -by (ALLGOALS (asm_simp_tac
  12.158 -	      (analz_image_freshK_ss addsimps [Says_Server_not_range])));
  12.159 -(*Fake*) 
  12.160 -by (spy_analz_tac 1);
  12.161 -qed_spec_mp "analz_image_freshK";
  12.162 -
  12.163 -Goal "[| evs \\<in> yahalom;  KAB \\<notin> range shrK |]              \
  12.164 -\      ==> Key K \\<in> analz (insert (Key KAB) (knows Spy evs)) =  \
  12.165 -\          (K = KAB | Key K \\<in> analz (knows Spy evs))";
  12.166 -by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
  12.167 -qed "analz_insert_freshK";
  12.168 -
  12.169 -
  12.170 -(*** The Key K uniquely identifies the Server's  message. **)
  12.171 -
  12.172 -
  12.173 -Goal "[| Says Server A                                                 \
  12.174 -\         {|Crypt (shrK A) {|Agent B, Key K, na, nb|}, X|} \\<in> set evs; \
  12.175 -\       Says Server A'                                                \
  12.176 -\         {|Crypt (shrK A') {|Agent B', Key K, na', nb'|}, X'|} \\<in> set evs; \
  12.177 -\       evs \\<in> yahalom |]                                    \
  12.178 -\    ==> A=A' & B=B' & na=na' & nb=nb'";
  12.179 -by (etac rev_mp 1);
  12.180 -by (etac rev_mp 1);
  12.181 -by (etac yahalom.induct 1);
  12.182 -by (ALLGOALS Asm_simp_tac);
  12.183 -(*YM4*)
  12.184 -by (Blast_tac 2);
  12.185 -(*YM3, by freshness*)
  12.186 -by (blast_tac (claset() addSEs knows_Spy_partsEs) 1);
  12.187 -qed "unique_session_keys";
  12.188 -
  12.189 -
  12.190 -(** Crucial secrecy property: Spy does not see the keys sent in msg YM3 **)
  12.191 -
  12.192 -Goal "[| A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]                \
  12.193 -\     ==> Says Server A                                        \
  12.194 -\           {|Crypt (shrK A) {|Agent B, Key K, na, nb|},       \
  12.195 -\             Crypt (shrK B) {|Agent A, Key K|}|}              \
  12.196 -\          \\<in> set evs -->                                       \
  12.197 -\         Notes Spy {|na, nb, Key K|} \\<notin> set evs -->           \
  12.198 -\         Key K \\<notin> analz (knows Spy evs)";
  12.199 -by (etac yahalom.induct 1);
  12.200 -by analz_knows_Spy_tac;
  12.201 -by (ALLGOALS
  12.202 -    (asm_simp_tac 
  12.203 -     (simpset() addsimps split_ifs @ pushes @
  12.204 -                         [analz_insert_eq, analz_insert_freshK])));
  12.205 -(*Oops*)
  12.206 -by (blast_tac (claset() addDs [unique_session_keys]) 3);
  12.207 -(*YM3*)
  12.208 -by (blast_tac (claset() delrules [impCE]
  12.209 -                        addSEs knows_Spy_partsEs
  12.210 -                        addIs [impOfSubs analz_subset_parts]) 2);
  12.211 -(*Fake*) 
  12.212 -by (spy_analz_tac 1);
  12.213 -val lemma = result() RS mp RS mp RSN(2,rev_notE);
  12.214 -
  12.215 -
  12.216 -(*Final version*)
  12.217 -Goal "[| Says Server A                                         \
  12.218 -\           {|Crypt (shrK A) {|Agent B, Key K, na, nb|},       \
  12.219 -\             Crypt (shrK B) {|Agent A, Key K|}|}              \
  12.220 -\          \\<in> set evs;                                          \
  12.221 -\        Notes Spy {|na, nb, Key K|} \\<notin> set evs;               \
  12.222 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]                \
  12.223 -\     ==> Key K \\<notin> analz (knows Spy evs)";
  12.224 -by (blast_tac (claset() addSEs [lemma]) 1);
  12.225 -qed "Spy_not_see_encrypted_key";
  12.226 -
  12.227 -
  12.228 -(** Security Guarantee for A upon receiving YM3 **)
  12.229 -
  12.230 -(*If the encrypted message appears then it originated with the Server*)
  12.231 -Goal "[| Crypt (shrK A) {|Agent B, Key K, na, nb|} \\<in> parts (knows Spy evs); \
  12.232 -\        A \\<notin> bad;  evs \\<in> yahalom |]                          \
  12.233 -\      ==> Says Server A                                            \
  12.234 -\           {|Crypt (shrK A) {|Agent B, Key K, na, nb|},            \
  12.235 -\             Crypt (shrK B) {|Agent A, Key K|}|}                   \
  12.236 -\          \\<in> set evs";
  12.237 -by (etac rev_mp 1);
  12.238 -by (parts_induct_tac 1);
  12.239 -by (Fake_parts_insert_tac 1);
  12.240 -qed "A_trusts_YM3";
  12.241 -
  12.242 -(*The obvious combination of A_trusts_YM3 with Spy_not_see_encrypted_key*)
  12.243 -Goal "[| Crypt (shrK A) {|Agent B, Key K, na, nb|} \\<in> parts (knows Spy evs); \
  12.244 -\        Notes Spy {|na, nb, Key K|} \\<notin> set evs;               \
  12.245 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]                \
  12.246 -\     ==> Key K \\<notin> analz (knows Spy evs)";
  12.247 -by (blast_tac (claset() addSDs [A_trusts_YM3, Spy_not_see_encrypted_key]) 1);
  12.248 -qed "A_gets_good_key";
  12.249 -
  12.250 -(** Security Guarantees for B upon receiving YM4 **)
  12.251 -
  12.252 -(*B knows, by the first part of A's message, that the Server distributed 
  12.253 -  the key for A and B.  But this part says nothing about nonces.*)
  12.254 -Goal "[| Crypt (shrK B) {|Agent A, Key K|} \\<in> parts (knows Spy evs);      \
  12.255 -\        B \\<notin> bad;  evs \\<in> yahalom |]                                 \
  12.256 -\     ==> \\<exists>NA NB. Says Server A                                    \
  12.257 -\                     {|Crypt (shrK A) {|Agent B, Key K,             \
  12.258 -\                                        Nonce NA, Nonce NB|},       \
  12.259 -\                       Crypt (shrK B) {|Agent A, Key K|}|}          \
  12.260 -\                    \\<in> set evs";
  12.261 -by (etac rev_mp 1);
  12.262 -by (parts_induct_tac 1);
  12.263 -by (Fake_parts_insert_tac 1);
  12.264 -(*YM3*)
  12.265 -by (Blast_tac 1);
  12.266 -qed "B_trusts_YM4_shrK";
  12.267 -
  12.268 -(*B knows, by the second part of A's message, that the Server distributed 
  12.269 -  the key quoting nonce NB.  This part says nothing about agent names. 
  12.270 -  Secrecy of NB is crucial.  Note that  Nonce NB \\<notin> analz(knows Spy evs)  must
  12.271 -  be the FIRST antecedent of the induction formula.*)
  12.272 -Goal "evs \\<in> yahalom                                          \
  12.273 -\     ==> Nonce NB \\<notin> analz (knows Spy evs) -->                  \
  12.274 -\         Crypt K (Nonce NB) \\<in> parts (knows Spy evs) -->         \
  12.275 -\         (\\<exists>A B NA. Says Server A                          \
  12.276 -\                     {|Crypt (shrK A) {|Agent B, Key K,     \
  12.277 -\                               Nonce NA, Nonce NB|},        \
  12.278 -\                       Crypt (shrK B) {|Agent A, Key K|}|}  \
  12.279 -\                    \\<in> set evs)";
  12.280 -by (parts_induct_tac 1);
  12.281 -by (ALLGOALS Clarify_tac);
  12.282 -(*YM3 & Fake*)
  12.283 -by (Blast_tac 2);
  12.284 -by (Fake_parts_insert_tac 1);
  12.285 -(*YM4*)
  12.286 -(*A is uncompromised because NB is secure;
  12.287 -  A's certificate guarantees the existence of the Server message*)
  12.288 -by (blast_tac (claset() addSDs [Gets_imp_Says, Crypt_Spy_analz_bad]
  12.289 -			addDs  [Says_imp_spies, analz.Inj, 
  12.290 -			        parts.Inj RS parts.Fst RS A_trusts_YM3]) 1);
  12.291 -bind_thm ("B_trusts_YM4_newK", result() RS mp RSN (2, rev_mp));
  12.292 -
  12.293 -
  12.294 -(**** Towards proving secrecy of Nonce NB ****)
  12.295 -
  12.296 -(** Lemmas about the predicate KeyWithNonce **)
  12.297 -
  12.298 -Goalw [KeyWithNonce_def]
  12.299 - "Says Server A                                              \
  12.300 -\         {|Crypt (shrK A) {|Agent B, Key K, na, Nonce NB|}, X|} \
  12.301 -\       \\<in> set evs ==> KeyWithNonce K NB evs";
  12.302 -by (Blast_tac 1);
  12.303 -qed "KeyWithNonceI";
  12.304 -
  12.305 -Goalw [KeyWithNonce_def]
  12.306 -   "KeyWithNonce K NB (Says S A X # evs) =                                    \
  12.307 -\ (Server = S &                                                            \
  12.308 -\  (\\<exists>B n X'. X = {|Crypt (shrK A) {|Agent B, Key K, n, Nonce NB|}, X'|}) \
  12.309 -\ | KeyWithNonce K NB evs)";
  12.310 -by (Simp_tac 1);
  12.311 -by (Blast_tac 1);
  12.312 -qed "KeyWithNonce_Says";
  12.313 -Addsimps [KeyWithNonce_Says];
  12.314 -
  12.315 -Goalw [KeyWithNonce_def]
  12.316 -   "KeyWithNonce K NB (Notes A X # evs) = KeyWithNonce K NB evs";
  12.317 -by (Simp_tac 1);
  12.318 -qed "KeyWithNonce_Notes";
  12.319 -Addsimps [KeyWithNonce_Notes];
  12.320 -
  12.321 -Goalw [KeyWithNonce_def]
  12.322 -   "KeyWithNonce K NB (Gets A X # evs) = KeyWithNonce K NB evs";
  12.323 -by (Simp_tac 1);
  12.324 -qed "KeyWithNonce_Gets";
  12.325 -Addsimps [KeyWithNonce_Gets];
  12.326 -
  12.327 -(*A fresh key cannot be associated with any nonce 
  12.328 -  (with respect to a given trace). *)
  12.329 -Goalw [KeyWithNonce_def]
  12.330 - "Key K \\<notin> used evs ==> ~ KeyWithNonce K NB evs";
  12.331 -by (blast_tac (claset() addSEs knows_Spy_partsEs) 1);
  12.332 -qed "fresh_not_KeyWithNonce";
  12.333 -
  12.334 -(*The Server message associates K with NB' and therefore not with any 
  12.335 -  other nonce NB.*)
  12.336 -Goalw [KeyWithNonce_def]
  12.337 - "[| Says Server A                                                \
  12.338 -\             {|Crypt (shrK A) {|Agent B, Key K, na, Nonce NB'|}, X|} \
  12.339 -\          \\<in> set evs;                                                 \
  12.340 -\        NB \\<noteq> NB';  evs \\<in> yahalom |]                                 \
  12.341 -\     ==> ~ KeyWithNonce K NB evs";
  12.342 -by (blast_tac (claset() addDs [unique_session_keys]) 1);
  12.343 -qed "Says_Server_KeyWithNonce";
  12.344 -
  12.345 -
  12.346 -(*The only nonces that can be found with the help of session keys are
  12.347 -  those distributed as nonce NB by the Server.  The form of the theorem
  12.348 -  recalls analz_image_freshK, but it is much more complicated.*)
  12.349 -
  12.350 -
  12.351 -(*As with analz_image_freshK, we take some pains to express the property
  12.352 -  as a logical equivalence so that the simplifier can apply it.*)
  12.353 -Goal "P --> (X \\<in> analz (G Un H)) --> (X \\<in> analz H)  ==> \
  12.354 -\     P --> (X \\<in> analz (G Un H)) = (X \\<in> analz H)";
  12.355 -by (blast_tac (claset() addIs [impOfSubs analz_mono]) 1);
  12.356 -val Nonce_secrecy_lemma = result();
  12.357 -
  12.358 -Goal "evs \\<in> yahalom ==>                                      \
  12.359 -\     (\\<forall>KK. KK <= - (range shrK) -->                      \
  12.360 -\          (\\<forall>K \\<in> KK. ~ KeyWithNonce K NB evs)   -->        \
  12.361 -\          (Nonce NB \\<in> analz (Key`KK Un (knows Spy evs))) =     \
  12.362 -\          (Nonce NB \\<in> analz (knows Spy evs)))";
  12.363 -by (etac yahalom.induct 1);
  12.364 -by analz_knows_Spy_tac;
  12.365 -by (REPEAT_FIRST (resolve_tac [impI RS allI]));
  12.366 -by (REPEAT_FIRST (rtac Nonce_secrecy_lemma));
  12.367 -(*For Oops, simplification proves NBa\\<noteq>NB.  By Says_Server_KeyWithNonce,
  12.368 -  we get (~ KeyWithNonce K NB evs); then simplification can apply the
  12.369 -  induction hypothesis with KK = {K}.*)
  12.370 -by (ALLGOALS  (*4 seconds*)
  12.371 -    (asm_simp_tac 
  12.372 -     (analz_image_freshK_ss 
  12.373 -       addsimps split_ifs
  12.374 -       addsimps [all_conj_distrib, ball_conj_distrib, analz_image_freshK,
  12.375 -		 KeyWithNonce_Says, KeyWithNonce_Notes, KeyWithNonce_Gets,
  12.376 -		 fresh_not_KeyWithNonce, Says_Server_not_range,
  12.377 -		 imp_disj_not1,		     (*Moves NBa\\<noteq>NB to the front*)
  12.378 -		 Says_Server_KeyWithNonce])));
  12.379 -(*Fake*) 
  12.380 -by (spy_analz_tac 1);
  12.381 -(*YM4*)  (** LEVEL 6 **)
  12.382 -by (thin_tac "\\<forall>KK. ?P KK" 1);
  12.383 -by (Clarify_tac 1);  
  12.384 -(*If A:bad then NBa is known, therefore NBa \\<noteq> NB.  Previous two steps make
  12.385 -  the next step faster.*)
  12.386 -by (blast_tac (claset() addSDs [Gets_imp_Says, Says_imp_spies, 
  12.387 -                                Crypt_Spy_analz_bad]
  12.388 -           addDs [analz.Inj,
  12.389 -                  parts.Inj RS parts.Fst RS A_trusts_YM3 RS KeyWithNonceI]) 1);
  12.390 -qed_spec_mp "Nonce_secrecy";
  12.391 -
  12.392 -
  12.393 -(*Version required below: if NB can be decrypted using a session key then it
  12.394 -  was distributed with that key.  The more general form above is required
  12.395 -  for the induction to carry through.*)
  12.396 -Goal "[| Says Server A                                               \
  12.397 -\         {|Crypt (shrK A) {|Agent B, Key KAB, na, Nonce NB'|}, X|}  \
  12.398 -\        \\<in> set evs;                                                  \
  12.399 -\        NB \\<noteq> NB';  KAB \\<notin> range shrK;  evs \\<in> yahalom |]            \
  12.400 -\     ==> (Nonce NB \\<in> analz (insert (Key KAB) (knows Spy evs))) =        \
  12.401 -\         (Nonce NB \\<in> analz (knows Spy evs))";
  12.402 -by (asm_simp_tac (analz_image_freshK_ss addsimps 
  12.403 -		  [Nonce_secrecy, Says_Server_KeyWithNonce]) 1);
  12.404 -qed "single_Nonce_secrecy";
  12.405 -
  12.406 -
  12.407 -(*** The Nonce NB uniquely identifies B's message. ***)
  12.408 -
  12.409 -Goal "[| Crypt (shrK B) {|Agent A, Nonce NA, nb|} \\<in> parts (knows Spy evs);    \
  12.410 -\        Crypt (shrK B') {|Agent A', Nonce NA', nb|} \\<in> parts (knows Spy evs); \
  12.411 -\       evs \\<in> yahalom;  B \\<notin> bad;  B' \\<notin> bad |]  \
  12.412 -\     ==> NA' = NA & A' = A & B' = B";
  12.413 -by (etac rev_mp 1);
  12.414 -by (etac rev_mp 1);
  12.415 -by (parts_induct_tac 1);
  12.416 -by (Fake_parts_insert_tac 1);
  12.417 -(*YM2, by freshness*)
  12.418 -by (blast_tac (claset() addSEs knows_Spy_partsEs) 1);
  12.419 -qed "unique_NB";
  12.420 -
  12.421 -
  12.422 -(*Variant useful for proving secrecy of NB.  Because nb is assumed to be 
  12.423 -  secret, we no longer must assume B, B' not bad.*)
  12.424 -Goal "[| Says C S   {|X,  Crypt (shrK B) {|Agent A, Nonce NA, nb|}|}    \
  12.425 -\          \\<in> set evs;                          \
  12.426 -\        Gets S' {|X', Crypt (shrK B') {|Agent A', Nonce NA', nb|}|}    \
  12.427 -\          \\<in> set evs;                                                   \
  12.428 -\        nb \\<notin> analz (knows Spy evs);  evs \\<in> yahalom |]                 \
  12.429 -\     ==> NA' = NA & A' = A & B' = B";
  12.430 -by (blast_tac (claset() addSDs [Gets_imp_Says, Crypt_Spy_analz_bad]
  12.431 -			addDs  [Says_imp_spies, unique_NB, parts.Inj, 
  12.432 -                                analz.Inj]) 1);
  12.433 -qed "Says_unique_NB";
  12.434 -
  12.435 -
  12.436 -(** A nonce value is never used both as NA and as NB **)
  12.437 -
  12.438 -Goal "evs \\<in> yahalom                     \
  12.439 -\ ==> Nonce NB \\<notin> analz (knows Spy evs) -->    \
  12.440 -\  Crypt (shrK B') {|Agent A', Nonce NB, nb'|} \\<in> parts(knows Spy evs) --> \
  12.441 -\  Crypt (shrK B)  {|Agent A, na, Nonce NB|} \\<notin> parts(knows Spy evs)";
  12.442 -by (parts_induct_tac 1);
  12.443 -by (Fake_parts_insert_tac 1);
  12.444 -by (blast_tac (claset() addDs [Gets_imp_knows_Spy RS analz.Inj]
  12.445 -                        addSIs [parts_insertI]
  12.446 -                        addSDs [parts.Body]) 1);
  12.447 -bind_thm ("no_nonce_YM1_YM2", result() RS mp RSN (2,rev_mp) RSN (2,rev_notE));
  12.448 -
  12.449 -(*more readable version cited in Yahalom paper*)
  12.450 -standard (result() RS mp RSN (2,rev_mp));
  12.451 -
  12.452 -(*The Server sends YM3 only in response to YM2.*)
  12.453 -Goal "[| Says Server A                                                \
  12.454 -\         {|Crypt (shrK A) {|Agent B, k, na, nb|}, X|} \\<in> set evs;     \
  12.455 -\        evs \\<in> yahalom |]                                             \
  12.456 -\     ==> Gets Server {| Agent B, Crypt (shrK B) {|Agent A, na, nb|} |} \
  12.457 -\            \\<in> set evs";
  12.458 -by (etac rev_mp 1);
  12.459 -by (etac yahalom.induct 1);
  12.460 -by Auto_tac;
  12.461 -qed "Says_Server_imp_YM2";
  12.462 -
  12.463 -
  12.464 -(*A vital theorem for B, that nonce NB remains secure from the Spy.*)
  12.465 -Goal "[| A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]  \
  12.466 -\ ==> (\\<forall>k. Notes Spy {|Nonce NA, Nonce NB, k|} \\<notin> set evs) -->      \
  12.467 -\  Says B Server                                                    \
  12.468 -\       {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, Nonce NB|}|} \
  12.469 -\  \\<in> set evs -->                                                    \
  12.470 -\  Nonce NB \\<notin> analz (knows Spy evs)";
  12.471 -by (etac yahalom.induct 1);
  12.472 -by analz_knows_Spy_tac;
  12.473 -by (ALLGOALS
  12.474 -    (asm_simp_tac 
  12.475 -     (simpset() addsimps split_ifs @ pushes @
  12.476 -               [new_keys_not_analzd, analz_insert_eq, analz_insert_freshK])));
  12.477 -(*Prove YM3 by showing that no NB can also be an NA*)
  12.478 -by (blast_tac (claset() addDs [Says_imp_knows_Spy RS parts.Inj]
  12.479 -	                addSEs [no_nonce_YM1_YM2, MPair_parts]
  12.480 -		        addDs  [Gets_imp_Says, Says_unique_NB]) 4);
  12.481 -(*YM2: similar freshness reasoning*) 
  12.482 -by (blast_tac (claset() addSDs [parts.Body]
  12.483 -		        addDs  [Gets_imp_Says,
  12.484 -				Says_imp_knows_Spy RS analz.Inj,
  12.485 -				impOfSubs analz_subset_parts]) 3);
  12.486 -(*YM1: NB=NA is impossible anyway, but NA is secret because it is fresh!*)
  12.487 -by (blast_tac (claset() addSIs [parts_insertI]
  12.488 -                        addSEs knows_Spy_partsEs) 2);
  12.489 -(*Fake*)
  12.490 -by (spy_analz_tac 1);
  12.491 -(** LEVEL 7: YM4 and Oops remain **)
  12.492 -by (ALLGOALS (Clarify_tac THEN' 
  12.493 -	      full_simp_tac (simpset() addsimps [all_conj_distrib])));
  12.494 -(*YM4: key K is visible to Spy, contradicting session key secrecy theorem*) 
  12.495 -(*Case analysis on Aa:bad; PROOF FAILED problems;
  12.496 -  use Says_unique_NB to identify message components: Aa=A, Ba=B*)  
  12.497 -by (blast_tac (claset() addSDs [Says_unique_NB, 
  12.498 -                                parts.Inj RS parts.Fst RS A_trusts_YM3]
  12.499 -			addDs [Gets_imp_knows_Spy RS analz.Inj, Gets_imp_Says,
  12.500 -                               Says_imp_spies, Says_Server_imp_YM2,
  12.501 -			       Spy_not_see_encrypted_key]) 1);
  12.502 -(** LEVEL 9 **)
  12.503 -(*Oops case: if the nonce is betrayed now, show that the Oops event is 
  12.504 -  covered by the quantified Oops assumption.*)
  12.505 -by (ftac Says_Server_imp_YM2 1 THEN assume_tac 1);  
  12.506 -by (case_tac "NB = NBa" 1);
  12.507 -(*If NB=NBa then all other components of the Oops message agree*)
  12.508 -by (blast_tac (claset() addDs [Says_unique_NB]) 1);
  12.509 -(*case NB \\<noteq> NBa*)
  12.510 -by (asm_simp_tac (simpset() addsimps [single_Nonce_secrecy]) 1);
  12.511 -by (blast_tac (claset() addSEs [no_nonce_YM1_YM2] (*to prove NB\\<noteq>NAa*)
  12.512 -		        addDs  [Says_imp_knows_Spy RS parts.Inj]) 1);
  12.513 -bind_thm ("Spy_not_see_NB", result() RSN(2,rev_mp) RSN(2,rev_mp));
  12.514 -
  12.515 -
  12.516 -(*B's session key guarantee from YM4.  The two certificates contribute to a
  12.517 -  single conclusion about the Server's message.  Note that the "Notes Spy"
  12.518 -  assumption must quantify over \\<forall>POSSIBLE keys instead of our particular K.
  12.519 -  If this run is broken and the spy substitutes a certificate containing an
  12.520 -  old key, B has no means of telling.*)
  12.521 -Goal "[| Gets B {|Crypt (shrK B) {|Agent A, Key K|},                  \
  12.522 -\                    Crypt K (Nonce NB)|} \\<in> set evs;                     \
  12.523 -\        Says B Server                                                   \
  12.524 -\          {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, Nonce NB|}|}   \
  12.525 -\          \\<in> set evs;                                                    \
  12.526 -\        \\<forall>k. Notes Spy {|Nonce NA, Nonce NB, k|} \\<notin> set evs;          \
  12.527 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]       \
  12.528 -\      ==> Says Server A                                                 \
  12.529 -\                  {|Crypt (shrK A) {|Agent B, Key K,                    \
  12.530 -\                            Nonce NA, Nonce NB|},                       \
  12.531 -\                    Crypt (shrK B) {|Agent A, Key K|}|}                 \
  12.532 -\            \\<in> set evs";
  12.533 -by (blast_tac (claset() addDs [Spy_not_see_NB, Says_unique_NB,
  12.534 -                               Says_Server_imp_YM2, B_trusts_YM4_newK]) 1);
  12.535 -qed "B_trusts_YM4";
  12.536 -
  12.537 -
  12.538 -(*The obvious combination of B_trusts_YM4 with Spy_not_see_encrypted_key*)
  12.539 -Goal "[| Gets B {|Crypt (shrK B) {|Agent A, Key K|},                  \
  12.540 -\                    Crypt K (Nonce NB)|} \\<in> set evs;                     \
  12.541 -\        Says B Server                                                   \
  12.542 -\          {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, Nonce NB|}|}   \
  12.543 -\          \\<in> set evs;                                                    \
  12.544 -\        \\<forall>k. Notes Spy {|Nonce NA, Nonce NB, k|} \\<notin> set evs;          \
  12.545 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]                \
  12.546 -\     ==> Key K \\<notin> analz (knows Spy evs)";
  12.547 -by (blast_tac (claset() addSDs [B_trusts_YM4, Spy_not_see_encrypted_key]) 1);
  12.548 -qed "B_gets_good_key";
  12.549 -
  12.550 -
  12.551 -(*** Authenticating B to A ***)
  12.552 -
  12.553 -(*The encryption in message YM2 tells us it cannot be faked.*)
  12.554 -Goal "evs \\<in> yahalom                                            \
  12.555 -\  ==> Crypt (shrK B) {|Agent A, Nonce NA, nb|} \\<in> parts (knows Spy evs) --> \
  12.556 -\   B \\<notin> bad -->                                              \
  12.557 -\   Says B Server {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, nb|}|}  \
  12.558 -\      \\<in> set evs";
  12.559 -by (parts_induct_tac 1);
  12.560 -by (Fake_parts_insert_tac 1);
  12.561 -bind_thm ("B_Said_YM2", result() RSN (2, rev_mp) RS mp);
  12.562 -
  12.563 -(*If the server sends YM3 then B sent YM2*)
  12.564 -Goal "evs \\<in> yahalom                                                      \
  12.565 -\  ==> Says Server A {|Crypt (shrK A) {|Agent B, Key K, Nonce NA, nb|}, X|} \
  12.566 -\      \\<in> set evs -->                                                     \
  12.567 -\   B \\<notin> bad -->                                                        \
  12.568 -\   Says B Server {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, nb|}|}  \
  12.569 -\              \\<in> set evs";
  12.570 -by (etac yahalom.induct 1);
  12.571 -by (ALLGOALS Asm_simp_tac);
  12.572 -(*YM4*)
  12.573 -by (Blast_tac 2);
  12.574 -(*YM3*)
  12.575 -by (blast_tac (claset() addSDs [B_Said_YM2, 
  12.576 -                                Says_imp_knows_Spy RS parts.Inj]) 1);
  12.577 -val lemma = result() RSN (2, rev_mp) RS mp |> standard;
  12.578 -
  12.579 -(*If A receives YM3 then B has used nonce NA (and therefore is alive)*)
  12.580 -Goal "[| Gets A {|Crypt (shrK A) {|Agent B, Key K, Nonce NA, nb|}, X|} \
  12.581 -\          \\<in> set evs;                                                    \
  12.582 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]                        \
  12.583 -\==> Says B Server {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, nb|}|} \
  12.584 -\      \\<in> set evs";
  12.585 -by (blast_tac (claset() addSDs [A_trusts_YM3, lemma]
  12.586 -		        addEs knows_Spy_partsEs) 1);
  12.587 -qed "YM3_auth_B_to_A";
  12.588 -
  12.589 -
  12.590 -(*** Authenticating A to B using the certificate Crypt K (Nonce NB) ***)
  12.591 -
  12.592 -(*Assuming the session key is secure, if both certificates are present then
  12.593 -  A has said NB.  We can't be sure about the rest of A's message, but only
  12.594 -  NB matters for freshness.*)  
  12.595 -Goal "evs \\<in> yahalom                                             \
  12.596 -\     ==> Key K \\<notin> analz (knows Spy evs) -->                     \
  12.597 -\         Crypt K (Nonce NB) \\<in> parts (knows Spy evs) -->         \
  12.598 -\         Crypt (shrK B) {|Agent A, Key K|} \\<in> parts (knows Spy evs) --> \
  12.599 -\         B \\<notin> bad -->                                         \
  12.600 -\         (\\<exists>X. Says A B {|X, Crypt K (Nonce NB)|} \\<in> set evs)";
  12.601 -by (parts_induct_tac 1);
  12.602 -(*Fake*)
  12.603 -by (Fake_parts_insert_tac 1);
  12.604 -(*YM3: by new_keys_not_used we note that Crypt K (Nonce NB) could not exist*)
  12.605 -by (fast_tac (claset() addSDs [Crypt_imp_keysFor] addss (simpset())) 1); 
  12.606 -(*YM4: was Crypt K (Nonce NB) the very last message?  If not, use ind. hyp.*)
  12.607 -by (asm_simp_tac (simpset() addsimps [ex_disj_distrib]) 1);
  12.608 -(*yes: apply unicity of session keys*)
  12.609 -by (blast_tac (claset() addSDs [Gets_imp_Says, A_trusts_YM3, B_trusts_YM4_shrK,
  12.610 -                                Crypt_Spy_analz_bad]
  12.611 -		addDs  [Says_imp_knows_Spy RS parts.Inj, 
  12.612 -                        Says_imp_spies RS analz.Inj, unique_session_keys]) 1);
  12.613 -qed_spec_mp "A_Said_YM3_lemma";
  12.614 -
  12.615 -(*If B receives YM4 then A has used nonce NB (and therefore is alive).
  12.616 -  Moreover, A associates K with NB (thus is talking about the same run).
  12.617 -  Other premises guarantee secrecy of K.*)
  12.618 -Goal "[| Gets B {|Crypt (shrK B) {|Agent A, Key K|},                  \
  12.619 -\                 Crypt K (Nonce NB)|} \\<in> set evs;                     \
  12.620 -\        Says B Server                                                   \
  12.621 -\          {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, Nonce NB|}|}   \
  12.622 -\          \\<in> set evs;                                                    \
  12.623 -\        (\\<forall>NA k. Notes Spy {|Nonce NA, Nonce NB, k|} \\<notin> set evs);     \
  12.624 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]       \
  12.625 -\     ==> \\<exists>X. Says A B {|X, Crypt K (Nonce NB)|} \\<in> set evs";
  12.626 -by (blast_tac (claset() addSIs [A_Said_YM3_lemma]
  12.627 -                   addDs [Spy_not_see_encrypted_key, B_trusts_YM4,
  12.628 -                          Gets_imp_Says, Says_imp_knows_Spy RS parts.Inj]) 1);
  12.629 -qed_spec_mp "YM4_imp_A_Said_YM3";
    13.1 --- a/src/HOL/Auth/Yahalom.thy	Wed Apr 11 11:53:54 2001 +0200
    13.2 +++ b/src/HOL/Auth/Yahalom.thy	Thu Apr 12 12:45:05 2001 +0200
    13.3 @@ -8,73 +8,633 @@
    13.4  From page 257 of
    13.5    Burrows, Abadi and Needham.  A Logic of Authentication.
    13.6    Proc. Royal Soc. 426 (1989)
    13.7 +
    13.8 +This theory has the prototypical example of a secrecy relation, KeyCryptNonce.
    13.9  *)
   13.10  
   13.11 -Yahalom = Shared + 
   13.12 +theory Yahalom = Shared:
   13.13  
   13.14 -consts  yahalom   :: event list set
   13.15 +consts  yahalom   :: "event list set"
   13.16  inductive "yahalom"
   13.17 -  intrs 
   13.18 +  intros 
   13.19           (*Initial trace is empty*)
   13.20 -    Nil  "[] \\<in> yahalom"
   13.21 +   Nil:  "[] \<in> yahalom"
   13.22  
   13.23           (*The spy MAY say anything he CAN say.  We do not expect him to
   13.24             invent new nonces here, but he can also use NS1.  Common to
   13.25             all similar protocols.*)
   13.26 -    Fake "[| evsf \\<in> yahalom;  X \\<in> synth (analz (knows Spy evsf)) |]
   13.27 -          ==> Says Spy B X  # evsf \\<in> yahalom"
   13.28 +   Fake: "[| evsf \<in> yahalom;  X \<in> synth (analz (knows Spy evsf)) |]
   13.29 +          ==> Says Spy B X  # evsf \<in> yahalom"
   13.30  
   13.31           (*A message that has been sent can be received by the
   13.32             intended recipient.*)
   13.33 -    Reception "[| evsr \\<in> yahalom;  Says A B X \\<in> set evsr |]
   13.34 -               ==> Gets B X # evsr \\<in> yahalom"
   13.35 +   Reception: "[| evsr \<in> yahalom;  Says A B X \<in> set evsr |]
   13.36 +               ==> Gets B X # evsr \<in> yahalom"
   13.37  
   13.38           (*Alice initiates a protocol run*)
   13.39 -    YM1  "[| evs1 \\<in> yahalom;  Nonce NA \\<notin> used evs1 |]
   13.40 -          ==> Says A B {|Agent A, Nonce NA|} # evs1 \\<in> yahalom"
   13.41 +   YM1:  "[| evs1 \<in> yahalom;  Nonce NA \<notin> used evs1 |]
   13.42 +          ==> Says A B {|Agent A, Nonce NA|} # evs1 \<in> yahalom"
   13.43  
   13.44           (*Bob's response to Alice's message.*)
   13.45 -    YM2  "[| evs2 \\<in> yahalom;  Nonce NB \\<notin> used evs2;
   13.46 -             Gets B {|Agent A, Nonce NA|} \\<in> set evs2 |]
   13.47 +   YM2:  "[| evs2 \<in> yahalom;  Nonce NB \<notin> used evs2;
   13.48 +             Gets B {|Agent A, Nonce NA|} \<in> set evs2 |]
   13.49            ==> Says B Server 
   13.50                    {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, Nonce NB|}|}
   13.51 -                # evs2 \\<in> yahalom"
   13.52 +                # evs2 \<in> yahalom"
   13.53  
   13.54           (*The Server receives Bob's message.  He responds by sending a
   13.55              new session key to Alice, with a packet for forwarding to Bob.*)
   13.56 -    YM3  "[| evs3 \\<in> yahalom;  Key KAB \\<notin> used evs3;
   13.57 +   YM3:  "[| evs3 \<in> yahalom;  Key KAB \<notin> used evs3;
   13.58               Gets Server 
   13.59                    {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, Nonce NB|}|}
   13.60 -               \\<in> set evs3 |]
   13.61 +               \<in> set evs3 |]
   13.62            ==> Says Server A
   13.63                     {|Crypt (shrK A) {|Agent B, Key KAB, Nonce NA, Nonce NB|},
   13.64                       Crypt (shrK B) {|Agent A, Key KAB|}|}
   13.65 -                # evs3 \\<in> yahalom"
   13.66 +                # evs3 \<in> yahalom"
   13.67  
   13.68           (*Alice receives the Server's (?) message, checks her Nonce, and
   13.69             uses the new session key to send Bob his Nonce.  The premise
   13.70 -           A \\<noteq> Server is needed to prove Says_Server_not_range.*)
   13.71 -    YM4  "[| evs4 \\<in> yahalom;  A \\<noteq> Server;
   13.72 +           A \<noteq> Server is needed to prove Says_Server_not_range.*)
   13.73 +   YM4:  "[| evs4 \<in> yahalom;  A \<noteq> Server;
   13.74               Gets A {|Crypt(shrK A) {|Agent B, Key K, Nonce NA, Nonce NB|}, X|}
   13.75 -                \\<in> set evs4;
   13.76 -             Says A B {|Agent A, Nonce NA|} \\<in> set evs4 |]
   13.77 -          ==> Says A B {|X, Crypt K (Nonce NB)|} # evs4 \\<in> yahalom"
   13.78 +                \<in> set evs4;
   13.79 +             Says A B {|Agent A, Nonce NA|} \<in> set evs4 |]
   13.80 +          ==> Says A B {|X, Crypt K (Nonce NB)|} # evs4 \<in> yahalom"
   13.81  
   13.82           (*This message models possible leaks of session keys.  The Nonces
   13.83             identify the protocol run.  Quoting Server here ensures they are
   13.84             correct.*)
   13.85 -    Oops "[| evso \\<in> yahalom;  
   13.86 +   Oops: "[| evso \<in> yahalom;  
   13.87               Says Server A {|Crypt (shrK A)
   13.88                                     {|Agent B, Key K, Nonce NA, Nonce NB|},
   13.89 -                             X|}  \\<in> set evso |]
   13.90 -          ==> Notes Spy {|Nonce NA, Nonce NB, Key K|} # evso \\<in> yahalom"
   13.91 +                             X|}  \<in> set evso |]
   13.92 +          ==> Notes Spy {|Nonce NA, Nonce NB, Key K|} # evso \<in> yahalom"
   13.93  
   13.94  
   13.95  constdefs 
   13.96 -  KeyWithNonce :: [key, nat, event list] => bool
   13.97 +  KeyWithNonce :: "[key, nat, event list] => bool"
   13.98    "KeyWithNonce K NB evs ==
   13.99 -     \\<exists>A B na X. 
  13.100 +     \<exists>A B na X. 
  13.101         Says Server A {|Crypt (shrK A) {|Agent B, Key K, na, Nonce NB|}, X|} 
  13.102 -         \\<in> set evs"
  13.103 +         \<in> set evs"
  13.104 +
  13.105 +
  13.106 +declare Says_imp_knows_Spy [THEN analz.Inj, dest]
  13.107 +declare parts.Body  [dest]
  13.108 +declare Fake_parts_insert_in_Un  [dest]
  13.109 +declare analz_into_parts [dest]
  13.110 +
  13.111 +(*A "possibility property": there are traces that reach the end*)
  13.112 +lemma "A \<noteq> Server  
  13.113 +      ==> \<exists>X NB K. \<exists>evs \<in> yahalom.           
  13.114 +             Says A B {|X, Crypt K (Nonce NB)|} \<in> set evs"
  13.115 +apply (intro exI bexI)
  13.116 +apply (rule_tac [2] yahalom.Nil
  13.117 +                    [THEN yahalom.YM1, THEN yahalom.Reception, 
  13.118 +                     THEN yahalom.YM2, THEN yahalom.Reception, 
  13.119 +                     THEN yahalom.YM3, THEN yahalom.Reception, 
  13.120 +                     THEN yahalom.YM4])
  13.121 +apply possibility
  13.122 +done
  13.123 +
  13.124 +lemma Gets_imp_Says:
  13.125 +     "[| Gets B X \<in> set evs; evs \<in> yahalom |] ==> \<exists>A. Says A B X \<in> set evs"
  13.126 +by (erule rev_mp, erule yahalom.induct, auto)
  13.127 +
  13.128 +(*Must be proved separately for each protocol*)
  13.129 +lemma Gets_imp_knows_Spy:
  13.130 +     "[| Gets B X \<in> set evs; evs \<in> yahalom |]  ==> X \<in> knows Spy evs"
  13.131 +by (blast dest!: Gets_imp_Says Says_imp_knows_Spy)
  13.132 +
  13.133 +declare Gets_imp_knows_Spy [THEN analz.Inj, dest]
  13.134 +
  13.135 +
  13.136 +(**** Inductive proofs about yahalom ****)
  13.137 +
  13.138 +(*Lets us treat YM4 using a similar argument as for the Fake case.*)
  13.139 +lemma YM4_analz_knows_Spy:
  13.140 +     "[| Gets A {|Crypt (shrK A) Y, X|} \<in> set evs;  evs \<in> yahalom |]   
  13.141 +      ==> X \<in> analz (knows Spy evs)"
  13.142 +by blast
  13.143 +
  13.144 +lemmas YM4_parts_knows_Spy = 
  13.145 +       YM4_analz_knows_Spy [THEN analz_into_parts, standard]
  13.146 +
  13.147 +(*For Oops*)
  13.148 +lemma YM4_Key_parts_knows_Spy:
  13.149 +     "Says Server A {|Crypt (shrK A) {|B,K,NA,NB|}, X|} \<in> set evs  
  13.150 +      ==> K \<in> parts (knows Spy evs)"
  13.151 +by (blast dest!: parts.Body Says_imp_knows_Spy [THEN parts.Inj])
  13.152 +
  13.153 +
  13.154 +(** Theorems of the form X \<notin> parts (knows Spy evs) imply that NOBODY
  13.155 +    sends messages containing X! **)
  13.156 +
  13.157 +(*Spy never sees a good agent's shared key!*)
  13.158 +lemma Spy_see_shrK [simp]:
  13.159 +     "evs \<in> yahalom ==> (Key (shrK A) \<in> parts (knows Spy evs)) = (A \<in> bad)"
  13.160 +apply (erule yahalom.induct, force, 
  13.161 +       drule_tac [6] YM4_parts_knows_Spy, simp_all)
  13.162 +apply blast+
  13.163 +done
  13.164 +
  13.165 +lemma Spy_analz_shrK [simp]:
  13.166 +     "evs \<in> yahalom ==> (Key (shrK A) \<in> analz (knows Spy evs)) = (A \<in> bad)"
  13.167 +by auto
  13.168 +
  13.169 +lemma Spy_see_shrK_D [dest!]:
  13.170 +     "[|Key (shrK A) \<in> parts (knows Spy evs);  evs \<in> yahalom|] ==> A \<in> bad"
  13.171 +by (blast dest: Spy_see_shrK)
  13.172 +
  13.173 +(*Nobody can have used non-existent keys!  Needed to apply analz_insert_Key*)
  13.174 +lemma new_keys_not_used [rule_format, simp]:
  13.175 + "evs \<in> yahalom ==> Key K \<notin> used evs --> K \<notin> keysFor (parts (knows Spy evs))"
  13.176 +apply (erule yahalom.induct, force, 
  13.177 +       frule_tac [6] YM4_parts_knows_Spy, simp_all)
  13.178 +(*Fake, YM3, YM4*)
  13.179 +apply (blast dest!: keysFor_parts_insert)+
  13.180 +done
  13.181 +
  13.182 +
  13.183 +(*Earlier, all protocol proofs declared this theorem.  
  13.184 +  But only a few proofs need it, e.g. Yahalom and Kerberos IV.*)
  13.185 +lemma new_keys_not_analzd:
  13.186 + "[|evs \<in> yahalom; Key K \<notin> used evs|] ==> K \<notin> keysFor (analz (knows Spy evs))"
  13.187 +by (blast dest: new_keys_not_used intro: keysFor_mono [THEN subsetD]) 
  13.188 +
  13.189 +
  13.190 +(*Describes the form of K when the Server sends this message.  Useful for
  13.191 +  Oops as well as main secrecy property.*)
  13.192 +lemma Says_Server_not_range [simp]:
  13.193 +     "[| Says Server A {|Crypt (shrK A) {|Agent B, Key K, na, nb|}, X|}  
  13.194 +           \<in> set evs;   evs \<in> yahalom |]                                 
  13.195 +      ==> K \<notin> range shrK"
  13.196 +apply (erule rev_mp, erule yahalom.induct, simp_all)
  13.197 +apply blast
  13.198 +done
  13.199 +
  13.200 +
  13.201 +(*For proofs involving analz.
  13.202 +val analz_knows_Spy_tac = 
  13.203 +    ftac YM4_analz_knows_Spy 7 THEN assume_tac 7
  13.204 +*)
  13.205 +
  13.206 +(****
  13.207 + The following is to prove theorems of the form
  13.208 +
  13.209 +  Key K \<in> analz (insert (Key KAB) (knows Spy evs)) ==>
  13.210 +  Key K \<in> analz (knows Spy evs)
  13.211 +
  13.212 + A more general formula must be proved inductively.
  13.213 +****)
  13.214 +
  13.215 +(** Session keys are not used to encrypt other session keys **)
  13.216 +
  13.217 +lemma analz_image_freshK [rule_format]:
  13.218 + "evs \<in> yahalom ==>                                
  13.219 +   \<forall>K KK. KK <= - (range shrK) -->                  
  13.220 +          (Key K \<in> analz (Key`KK Un (knows Spy evs))) =   
  13.221 +          (K \<in> KK | Key K \<in> analz (knows Spy evs))"
  13.222 +apply (erule yahalom.induct, force, 
  13.223 +       drule_tac [6] YM4_analz_knows_Spy)
  13.224 +apply analz_freshK
  13.225 +apply spy_analz
  13.226 +apply (simp only: Says_Server_not_range analz_image_freshK_simps)
  13.227 +done
  13.228 +
  13.229 +lemma analz_insert_freshK:
  13.230 +     "[| evs \<in> yahalom;  KAB \<notin> range shrK |] ==>      
  13.231 +      Key K \<in> analz (insert (Key KAB) (knows Spy evs)) =   
  13.232 +      (K = KAB | Key K \<in> analz (knows Spy evs))"
  13.233 +by (simp only: analz_image_freshK analz_image_freshK_simps)
  13.234 +
  13.235 +
  13.236 +(*** The Key K uniquely identifies the Server's  message. **)
  13.237 +
  13.238 +lemma unique_session_keys:
  13.239 +     "[| Says Server A                                                  
  13.240 +          {|Crypt (shrK A) {|Agent B, Key K, na, nb|}, X|} \<in> set evs;  
  13.241 +        Says Server A'                                                 
  13.242 +          {|Crypt (shrK A') {|Agent B', Key K, na', nb'|}, X'|} \<in> set evs;  
  13.243 +        evs \<in> yahalom |]                                     
  13.244 +     ==> A=A' & B=B' & na=na' & nb=nb'"
  13.245 +apply (erule rev_mp, erule rev_mp)
  13.246 +apply (erule yahalom.induct, simp_all)
  13.247 +(*YM3, by freshness, and YM4*)
  13.248 +apply blast+
  13.249 +done
  13.250 +
  13.251 +
  13.252 +(** Crucial secrecy property: Spy does not see the keys sent in msg YM3 **)
  13.253 +
  13.254 +lemma secrecy_lemma:
  13.255 +     "[| A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]                 
  13.256 +      ==> Says Server A                                         
  13.257 +            {|Crypt (shrK A) {|Agent B, Key K, na, nb|},        
  13.258 +              Crypt (shrK B) {|Agent A, Key K|}|}               
  13.259 +           \<in> set evs -->                                        
  13.260 +          Notes Spy {|na, nb, Key K|} \<notin> set evs -->            
  13.261 +          Key K \<notin> analz (knows Spy evs)"
  13.262 +apply (erule yahalom.induct, force, 
  13.263 +       drule_tac [6] YM4_analz_knows_Spy)
  13.264 +apply (simp_all add: pushes analz_insert_eq analz_insert_freshK)
  13.265 +apply spy_analz  (*Fake*)
  13.266 +apply (blast dest: unique_session_keys)+  (*YM3, Oops*)
  13.267 +done
  13.268 +
  13.269 +(*Final version*)
  13.270 +lemma Spy_not_see_encrypted_key:
  13.271 +     "[| Says Server A                                          
  13.272 +            {|Crypt (shrK A) {|Agent B, Key K, na, nb|},        
  13.273 +              Crypt (shrK B) {|Agent A, Key K|}|}               
  13.274 +           \<in> set evs;                                           
  13.275 +         Notes Spy {|na, nb, Key K|} \<notin> set evs;                
  13.276 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]                 
  13.277 +      ==> Key K \<notin> analz (knows Spy evs)"
  13.278 +by (blast dest: secrecy_lemma)
  13.279 +
  13.280 +
  13.281 +(** Security Guarantee for A upon receiving YM3 **)
  13.282 +
  13.283 +(*If the encrypted message appears then it originated with the Server*)
  13.284 +lemma A_trusts_YM3:
  13.285 +     "[| Crypt (shrK A) {|Agent B, Key K, na, nb|} \<in> parts (knows Spy evs);  
  13.286 +         A \<notin> bad;  evs \<in> yahalom |]                           
  13.287 +       ==> Says Server A                                             
  13.288 +            {|Crypt (shrK A) {|Agent B, Key K, na, nb|},             
  13.289 +              Crypt (shrK B) {|Agent A, Key K|}|}                    
  13.290 +           \<in> set evs"
  13.291 +apply (erule rev_mp)
  13.292 +apply (erule yahalom.induct, force, 
  13.293 +       frule_tac [6] YM4_parts_knows_Spy, simp_all)
  13.294 +(*Fake, YM3*)
  13.295 +apply blast+
  13.296 +done
  13.297 +
  13.298 +(*The obvious combination of A_trusts_YM3 with Spy_not_see_encrypted_key*)
  13.299 +lemma A_gets_good_key:
  13.300 +     "[| Crypt (shrK A) {|Agent B, Key K, na, nb|} \<in> parts (knows Spy evs);  
  13.301 +         Notes Spy {|na, nb, Key K|} \<notin> set evs;                
  13.302 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]                 
  13.303 +      ==> Key K \<notin> analz (knows Spy evs)"
  13.304 +by (blast dest!: A_trusts_YM3 Spy_not_see_encrypted_key)
  13.305 +
  13.306 +(** Security Guarantees for B upon receiving YM4 **)
  13.307 +
  13.308 +(*B knows, by the first part of A's message, that the Server distributed 
  13.309 +  the key for A and B.  But this part says nothing about nonces.*)
  13.310 +lemma B_trusts_YM4_shrK:
  13.311 +     "[| Crypt (shrK B) {|Agent A, Key K|} \<in> parts (knows Spy evs);       
  13.312 +         B \<notin> bad;  evs \<in> yahalom |]                                  
  13.313 +      ==> \<exists>NA NB. Says Server A                                     
  13.314 +                      {|Crypt (shrK A) {|Agent B, Key K,              
  13.315 +                                         Nonce NA, Nonce NB|},        
  13.316 +                        Crypt (shrK B) {|Agent A, Key K|}|}           
  13.317 +                     \<in> set evs"
  13.318 +apply (erule rev_mp)
  13.319 +apply (erule yahalom.induct, force, 
  13.320 +       frule_tac [6] YM4_parts_knows_Spy, simp_all)
  13.321 +(*Fake, YM3*)
  13.322 +apply blast+
  13.323 +done
  13.324 +
  13.325 +(*B knows, by the second part of A's message, that the Server distributed 
  13.326 +  the key quoting nonce NB.  This part says nothing about agent names. 
  13.327 +  Secrecy of NB is crucial.  Note that  Nonce NB \<notin> analz(knows Spy evs)  must
  13.328 +  be the FIRST antecedent of the induction formula.*)
  13.329 +lemma B_trusts_YM4_newK[rule_format]:
  13.330 +     "[|Crypt K (Nonce NB) \<in> parts (knows Spy evs);
  13.331 +        Nonce NB \<notin> analz (knows Spy evs);  evs \<in> yahalom|]
  13.332 +      ==> \<exists>A B NA. Says Server A                           
  13.333 +                      {|Crypt (shrK A) {|Agent B, Key K, Nonce NA, Nonce NB|},
  13.334 +                        Crypt (shrK B) {|Agent A, Key K|}|}   
  13.335 +                     \<in> set evs"
  13.336 +apply (erule rev_mp, erule rev_mp)
  13.337 +apply (erule yahalom.induct, force, 
  13.338 +       frule_tac [6] YM4_parts_knows_Spy)
  13.339 +apply (analz_mono_contra, simp_all)
  13.340 +(*Fake, YM3*)
  13.341 +apply blast
  13.342 +apply blast
  13.343 +(*YM4*)
  13.344 +(*A is uncompromised because NB is secure
  13.345 +  A's certificate guarantees the existence of the Server message*)
  13.346 +apply (blast dest!: Gets_imp_Says Crypt_Spy_analz_bad 
  13.347 +             dest: Says_imp_spies 
  13.348 +                   parts.Inj [THEN parts.Fst, THEN A_trusts_YM3])
  13.349 +done
  13.350 +
  13.351 +
  13.352 +(**** Towards proving secrecy of Nonce NB ****)
  13.353 +
  13.354 +(** Lemmas about the predicate KeyWithNonce **)
  13.355 +
  13.356 +lemma KeyWithNonceI: 
  13.357 + "Says Server A                                               
  13.358 +          {|Crypt (shrK A) {|Agent B, Key K, na, Nonce NB|}, X|}  
  13.359 +        \<in> set evs ==> KeyWithNonce K NB evs"
  13.360 +by (unfold KeyWithNonce_def, blast)
  13.361 +
  13.362 +lemma KeyWithNonce_Says [simp]: 
  13.363 +   "KeyWithNonce K NB (Says S A X # evs) =                                     
  13.364 +      (Server = S &
  13.365 +       (\<exists>B n X'. X = {|Crypt (shrK A) {|Agent B, Key K, n, Nonce NB|}, X'|})  
  13.366 +      | KeyWithNonce K NB evs)"
  13.367 +by (simp add: KeyWithNonce_def, blast)
  13.368 +
  13.369 +
  13.370 +lemma KeyWithNonce_Notes [simp]: 
  13.371 +   "KeyWithNonce K NB (Notes A X # evs) = KeyWithNonce K NB evs"
  13.372 +by (simp add: KeyWithNonce_def)
  13.373 +
  13.374 +lemma KeyWithNonce_Gets [simp]: 
  13.375 +   "KeyWithNonce K NB (Gets A X # evs) = KeyWithNonce K NB evs"
  13.376 +by (simp add: KeyWithNonce_def)
  13.377 +
  13.378 +(*A fresh key cannot be associated with any nonce 
  13.379 +  (with respect to a given trace). *)
  13.380 +lemma fresh_not_KeyWithNonce: 
  13.381 + "Key K \<notin> used evs ==> ~ KeyWithNonce K NB evs"
  13.382 +by (unfold KeyWithNonce_def, blast)
  13.383 +
  13.384 +(*The Server message associates K with NB' and therefore not with any 
  13.385 +  other nonce NB.*)
  13.386 +lemma Says_Server_KeyWithNonce: 
  13.387 + "[| Says Server A {|Crypt (shrK A) {|Agent B, Key K, na, Nonce NB'|}, X|}  
  13.388 +       \<in> set evs;                                                  
  13.389 +     NB \<noteq> NB';  evs \<in> yahalom |]                                  
  13.390 +  ==> ~ KeyWithNonce K NB evs"
  13.391 +by (unfold KeyWithNonce_def, blast dest: unique_session_keys)
  13.392 +
  13.393 +
  13.394 +(*The only nonces that can be found with the help of session keys are
  13.395 +  those distributed as nonce NB by the Server.  The form of the theorem
  13.396 +  recalls analz_image_freshK, but it is much more complicated.*)
  13.397 +
  13.398 +
  13.399 +(*As with analz_image_freshK, we take some pains to express the property
  13.400 +  as a logical equivalence so that the simplifier can apply it.*)
  13.401 +lemma Nonce_secrecy_lemma:
  13.402 +     "P --> (X \<in> analz (G Un H)) --> (X \<in> analz H)  ==>  
  13.403 +      P --> (X \<in> analz (G Un H)) = (X \<in> analz H)"
  13.404 +by (blast intro: analz_mono [THEN subsetD])
  13.405 +
  13.406 +lemma Nonce_secrecy:
  13.407 +     "evs \<in> yahalom ==>                                       
  13.408 +      (\<forall>KK. KK <= - (range shrK) -->                       
  13.409 +           (\<forall>K \<in> KK. ~ KeyWithNonce K NB evs)   -->         
  13.410 +           (Nonce NB \<in> analz (Key`KK Un (knows Spy evs))) =      
  13.411 +           (Nonce NB \<in> analz (knows Spy evs)))"
  13.412 +apply (erule yahalom.induct, force, 
  13.413 +       frule_tac [6] YM4_analz_knows_Spy)
  13.414 +apply (safe del: allI impI intro!: Nonce_secrecy_lemma [THEN impI, THEN allI])
  13.415 +apply (simp_all del: image_insert image_Un 
  13.416 +       add: analz_image_freshK_simps split_ifs
  13.417 +            all_conj_distrib ball_conj_distrib 
  13.418 +            analz_image_freshK fresh_not_KeyWithNonce
  13.419 +            imp_disj_not1               (*Moves NBa\<noteq>NB to the front*)
  13.420 +            Says_Server_KeyWithNonce)
  13.421 +(*For Oops, simplification proves NBa\<noteq>NB.  By Says_Server_KeyWithNonce,
  13.422 +  we get (~ KeyWithNonce K NB evs); then simplification can apply the
  13.423 +  induction hypothesis with KK = {K}.*)
  13.424 +(*Fake*) 
  13.425 +apply spy_analz
  13.426 +(*YM4*)  (** LEVEL 6 **)
  13.427 +apply (erule_tac V = "\<forall>KK. ?P KK" in thin_rl)
  13.428 +apply clarify
  13.429 +(*If A \<in> bad then NBa is known, therefore NBa \<noteq> NB.  Previous two steps make
  13.430 +  the next step faster.*)
  13.431 +apply (blast dest!: Gets_imp_Says Says_imp_spies Crypt_Spy_analz_bad
  13.432 +         dest: analz.Inj
  13.433 +           parts.Inj [THEN parts.Fst, THEN A_trusts_YM3, THEN KeyWithNonceI])
  13.434 +done
  13.435 +
  13.436 +
  13.437 +(*Version required below: if NB can be decrypted using a session key then it
  13.438 +  was distributed with that key.  The more general form above is required
  13.439 +  for the induction to carry through.*)
  13.440 +lemma single_Nonce_secrecy:
  13.441 +     "[| Says Server A                                                
  13.442 +          {|Crypt (shrK A) {|Agent B, Key KAB, na, Nonce NB'|}, X|}   
  13.443 +         \<in> set evs;                                                   
  13.444 +         NB \<noteq> NB';  KAB \<notin> range shrK;  evs \<in> yahalom |]             
  13.445 +      ==> (Nonce NB \<in> analz (insert (Key KAB) (knows Spy evs))) =         
  13.446 +          (Nonce NB \<in> analz (knows Spy evs))"
  13.447 +by (simp_all del: image_insert image_Un imp_disjL
  13.448 +             add: analz_image_freshK_simps split_ifs
  13.449 +                  Nonce_secrecy Says_Server_KeyWithNonce);
  13.450 +
  13.451 +
  13.452 +(*** The Nonce NB uniquely identifies B's message. ***)
  13.453 +
  13.454 +lemma unique_NB:
  13.455 +     "[| Crypt (shrK B) {|Agent A, Nonce NA, nb|} \<in> parts (knows Spy evs);     
  13.456 +         Crypt (shrK B') {|Agent A', Nonce NA', nb|} \<in> parts (knows Spy evs);  
  13.457 +        evs \<in> yahalom;  B \<notin> bad;  B' \<notin> bad |]   
  13.458 +      ==> NA' = NA & A' = A & B' = B"
  13.459 +apply (erule rev_mp, erule rev_mp)
  13.460 +apply (erule yahalom.induct, force, 
  13.461 +       frule_tac [6] YM4_parts_knows_Spy, simp_all)
  13.462 +(*Fake, and YM2 by freshness*)
  13.463 +apply blast+
  13.464 +done
  13.465 +
  13.466 +
  13.467 +(*Variant useful for proving secrecy of NB.  Because nb is assumed to be 
  13.468 +  secret, we no longer must assume B, B' not bad.*)
  13.469 +lemma Says_unique_NB:
  13.470 +     "[| Says C S   {|X,  Crypt (shrK B) {|Agent A, Nonce NA, nb|}|}     
  13.471 +           \<in> set evs;                           
  13.472 +         Gets S' {|X', Crypt (shrK B') {|Agent A', Nonce NA', nb|}|}     
  13.473 +           \<in> set evs;                                                    
  13.474 +         nb \<notin> analz (knows Spy evs);  evs \<in> yahalom |]                  
  13.475 +      ==> NA' = NA & A' = A & B' = B"
  13.476 +by (blast dest!: Gets_imp_Says Crypt_Spy_analz_bad 
  13.477 +          dest: Says_imp_spies unique_NB parts.Inj analz.Inj)
  13.478 +
  13.479 +
  13.480 +(** A nonce value is never used both as NA and as NB **)
  13.481 +
  13.482 +lemma no_nonce_YM1_YM2:
  13.483 +     "[|Crypt (shrK B') {|Agent A', Nonce NB, nb'|} \<in> parts(knows Spy evs);
  13.484 +        Nonce NB \<notin> analz (knows Spy evs);  evs \<in> yahalom|]
  13.485 +  ==> Crypt (shrK B)  {|Agent A, na, Nonce NB|} \<notin> parts(knows Spy evs)"
  13.486 +apply (erule rev_mp, erule rev_mp)
  13.487 +apply (erule yahalom.induct, force, 
  13.488 +       frule_tac [6] YM4_parts_knows_Spy)
  13.489 +apply (analz_mono_contra, simp_all)
  13.490 +(*Fake, YM2*)
  13.491 +apply blast+
  13.492 +done
  13.493 +
  13.494 +(*The Server sends YM3 only in response to YM2.*)
  13.495 +lemma Says_Server_imp_YM2:
  13.496 +     "[| Says Server A {|Crypt (shrK A) {|Agent B, k, na, nb|}, X|} \<in> set evs;
  13.497 +         evs \<in> yahalom |]                                              
  13.498 +      ==> Gets Server {| Agent B, Crypt (shrK B) {|Agent A, na, nb|} |}  
  13.499 +             \<in> set evs"
  13.500 +apply (erule rev_mp, erule yahalom.induct)
  13.501 +apply auto
  13.502 +done
  13.503 +
  13.504 +
  13.505 +(*A vital theorem for B, that nonce NB remains secure from the Spy.*)
  13.506 +lemma Spy_not_see_NB :
  13.507 +     "[| Says B Server                                                     
  13.508 +	        {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, Nonce NB|}|}  
  13.509 +	   \<in> set evs;
  13.510 +	 (\<forall>k. Notes Spy {|Nonce NA, Nonce NB, k|} \<notin> set evs);
  13.511 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]   
  13.512 +      ==> Nonce NB \<notin> analz (knows Spy evs)"
  13.513 +apply (erule rev_mp, erule rev_mp)
  13.514 +apply (erule yahalom.induct, force, 
  13.515 +       frule_tac [6] YM4_analz_knows_Spy)
  13.516 +apply (simp_all add: split_ifs pushes new_keys_not_analzd analz_insert_eq
  13.517 +                     analz_insert_freshK)
  13.518 +(*Fake*)
  13.519 +apply spy_analz
  13.520 +(*YM1: NB=NA is impossible anyway, but NA is secret because it is fresh!*)
  13.521 +apply blast
  13.522 +(*YM2*)
  13.523 +apply blast
  13.524 +(*Prove YM3 by showing that no NB can also be an NA*)
  13.525 +apply (blast dest!: no_nonce_YM1_YM2 dest: Gets_imp_Says Says_unique_NB)
  13.526 +(** LEVEL 7: YM4 and Oops remain **)
  13.527 +apply (clarify, simp add: all_conj_distrib)
  13.528 +(*YM4: key K is visible to Spy, contradicting session key secrecy theorem*) 
  13.529 +(*Case analysis on Aa:bad; PROOF FAILED problems
  13.530 +  use Says_unique_NB to identify message components: Aa=A, Ba=B*)  
  13.531 +apply (blast dest!: Says_unique_NB 
  13.532 +                    parts.Inj [THEN parts.Fst, THEN A_trusts_YM3] 
  13.533 +             dest: Gets_imp_Says Says_imp_spies Says_Server_imp_YM2
  13.534 +                   Spy_not_see_encrypted_key)
  13.535 +(*Oops case: if the nonce is betrayed now, show that the Oops event is 
  13.536 +  covered by the quantified Oops assumption.*)
  13.537 +apply (clarify, simp add: all_conj_distrib)
  13.538 +apply (frule Says_Server_imp_YM2, assumption)
  13.539 +apply (case_tac "NB = NBa")
  13.540 +(*If NB=NBa then all other components of the Oops message agree*)
  13.541 +apply (blast dest: Says_unique_NB)
  13.542 +(*case NB \<noteq> NBa*)
  13.543 +apply (simp add: single_Nonce_secrecy)
  13.544 +apply (blast dest!: no_nonce_YM1_YM2 (*to prove NB\<noteq>NAa*))
  13.545 +done
  13.546 +
  13.547 +
  13.548 +(*B's session key guarantee from YM4.  The two certificates contribute to a
  13.549 +  single conclusion about the Server's message.  Note that the "Notes Spy"
  13.550 +  assumption must quantify over \<forall>POSSIBLE keys instead of our particular K.
  13.551 +  If this run is broken and the spy substitutes a certificate containing an
  13.552 +  old key, B has no means of telling.*)
  13.553 +lemma B_trusts_YM4:
  13.554 +     "[| Gets B {|Crypt (shrK B) {|Agent A, Key K|},                   
  13.555 +                  Crypt K (Nonce NB)|} \<in> set evs;                      
  13.556 +         Says B Server                                                    
  13.557 +           {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, Nonce NB|}|}    
  13.558 +           \<in> set evs;                                                     
  13.559 +         \<forall>k. Notes Spy {|Nonce NA, Nonce NB, k|} \<notin> set evs;           
  13.560 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]        
  13.561 +       ==> Says Server A                                                  
  13.562 +                   {|Crypt (shrK A) {|Agent B, Key K,                     
  13.563 +                             Nonce NA, Nonce NB|},                        
  13.564 +                     Crypt (shrK B) {|Agent A, Key K|}|}                  
  13.565 +             \<in> set evs"
  13.566 +by (blast dest: Spy_not_see_NB Says_unique_NB 
  13.567 +                Says_Server_imp_YM2 B_trusts_YM4_newK)
  13.568 +
  13.569 +
  13.570 +
  13.571 +(*The obvious combination of B_trusts_YM4 with Spy_not_see_encrypted_key*)
  13.572 +lemma B_gets_good_key:
  13.573 +     "[| Gets B {|Crypt (shrK B) {|Agent A, Key K|},
  13.574 +                  Crypt K (Nonce NB)|} \<in> set evs;
  13.575 +         Says B Server                                                    
  13.576 +           {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, Nonce NB|}|}    
  13.577 +           \<in> set evs;                                                     
  13.578 +         \<forall>k. Notes Spy {|Nonce NA, Nonce NB, k|} \<notin> set evs;           
  13.579 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]                 
  13.580 +      ==> Key K \<notin> analz (knows Spy evs)"
  13.581 +by (blast dest!: B_trusts_YM4 Spy_not_see_encrypted_key)
  13.582 +
  13.583 +
  13.584 +(*** Authenticating B to A ***)
  13.585 +
  13.586 +(*The encryption in message YM2 tells us it cannot be faked.*)
  13.587 +lemma B_Said_YM2 [rule_format]:
  13.588 +     "[|Crypt (shrK B) {|Agent A, Nonce NA, nb|} \<in> parts (knows Spy evs);
  13.589 +        evs \<in> yahalom|]
  13.590 +      ==> B \<notin> bad -->
  13.591 +          Says B Server {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, nb|}|}
  13.592 +            \<in> set evs"
  13.593 +apply (erule rev_mp, erule yahalom.induct, force, 
  13.594 +       frule_tac [6] YM4_parts_knows_Spy, simp_all)
  13.595 +(*Fake*)
  13.596 +apply blast
  13.597 +done
  13.598 +
  13.599 +(*If the server sends YM3 then B sent YM2*)
  13.600 +lemma YM3_auth_B_to_A_lemma:
  13.601 +     "[|Says Server A {|Crypt (shrK A) {|Agent B, Key K, Nonce NA, nb|}, X|}  
  13.602 +       \<in> set evs;  evs \<in> yahalom|]
  13.603 +      ==> B \<notin> bad -->                                                         
  13.604 +          Says B Server {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, nb|}|}
  13.605 +            \<in> set evs"
  13.606 +apply (erule rev_mp, erule yahalom.induct, simp_all)
  13.607 +(*YM3, YM4*)
  13.608 +apply (blast dest!: B_Said_YM2)+
  13.609 +done
  13.610 +
  13.611 +(*If A receives YM3 then B has used nonce NA (and therefore is alive)*)
  13.612 +lemma YM3_auth_B_to_A:
  13.613 +     "[| Gets A {|Crypt (shrK A) {|Agent B, Key K, Nonce NA, nb|}, X|}  
  13.614 +           \<in> set evs;                                                     
  13.615 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]                         
  13.616 +      ==> Says B Server {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, nb|}|}  
  13.617 +       \<in> set evs"
  13.618 +by (blast dest!: A_trusts_YM3 YM3_auth_B_to_A_lemma elim: knows_Spy_partsEs)
  13.619 +
  13.620 +
  13.621 +(*** Authenticating A to B using the certificate Crypt K (Nonce NB) ***)
  13.622 +
  13.623 +(*Assuming the session key is secure, if both certificates are present then
  13.624 +  A has said NB.  We can't be sure about the rest of A's message, but only
  13.625 +  NB matters for freshness.*)  
  13.626 +lemma A_Said_YM3_lemma [rule_format]:
  13.627 +     "evs \<in> yahalom
  13.628 +      ==> Key K \<notin> analz (knows Spy evs) -->
  13.629 +          Crypt K (Nonce NB) \<in> parts (knows Spy evs) -->
  13.630 +          Crypt (shrK B) {|Agent A, Key K|} \<in> parts (knows Spy evs) -->
  13.631 +          B \<notin> bad -->
  13.632 +          (\<exists>X. Says A B {|X, Crypt K (Nonce NB)|} \<in> set evs)"
  13.633 +apply (erule yahalom.induct, force, 
  13.634 +       frule_tac [6] YM4_parts_knows_Spy)
  13.635 +apply (analz_mono_contra, simp_all)
  13.636 +(*Fake*)
  13.637 +apply blast
  13.638 +(*YM3: by new_keys_not_used we note that Crypt K (Nonce NB) could not exist*)
  13.639 +apply (force dest!: Crypt_imp_keysFor)
  13.640 +(*YM4: was Crypt K (Nonce NB) the very last message?  If not, use ind. hyp.*)
  13.641 +apply (simp add: ex_disj_distrib)
  13.642 +(*yes: apply unicity of session keys*)
  13.643 +apply (blast dest!: Gets_imp_Says A_trusts_YM3 B_trusts_YM4_shrK
  13.644 +                    Crypt_Spy_analz_bad 
  13.645 +             dest: Says_imp_knows_Spy [THEN parts.Inj] unique_session_keys)
  13.646 +done
  13.647 +
  13.648 +(*If B receives YM4 then A has used nonce NB (and therefore is alive).
  13.649 +  Moreover, A associates K with NB (thus is talking about the same run).
  13.650 +  Other premises guarantee secrecy of K.*)
  13.651 +lemma YM4_imp_A_Said_YM3 [rule_format]:
  13.652 +     "[| Gets B {|Crypt (shrK B) {|Agent A, Key K|},
  13.653 +                  Crypt K (Nonce NB)|} \<in> set evs;
  13.654 +         Says B Server
  13.655 +           {|Agent B, Crypt (shrK B) {|Agent A, Nonce NA, Nonce NB|}|}
  13.656 +           \<in> set evs;
  13.657 +         (\<forall>NA k. Notes Spy {|Nonce NA, Nonce NB, k|} \<notin> set evs);
  13.658 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]
  13.659 +      ==> \<exists>X. Says A B {|X, Crypt K (Nonce NB)|} \<in> set evs"
  13.660 +by (blast intro!: A_Said_YM3_lemma 
  13.661 +          dest: Spy_not_see_encrypted_key B_trusts_YM4 Gets_imp_Says)
  13.662  
  13.663  end
    14.1 --- a/src/HOL/Auth/Yahalom2.ML	Wed Apr 11 11:53:54 2001 +0200
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,378 +0,0 @@
    14.4 -(*  Title:      HOL/Auth/Yahalom2
    14.5 -    ID:         $Id$
    14.6 -    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
    14.7 -    Copyright   1996  University of Cambridge
    14.8 -
    14.9 -Inductive relation "yahalom" for the Yahalom protocol, Variant 2.
   14.10 -
   14.11 -This version trades encryption of NB for additional explicitness in YM3.
   14.12 -
   14.13 -From page 259 of
   14.14 -  Burrows, Abadi and Needham.  A Logic of Authentication.
   14.15 -  Proc. Royal Soc. 426 (1989)
   14.16 -*)
   14.17 -
   14.18 -AddDs  [Says_imp_knows_Spy RS parts.Inj, parts.Body];
   14.19 -AddDs  [impOfSubs analz_subset_parts, impOfSubs Fake_parts_insert];
   14.20 -
   14.21 -
   14.22 -(*A "possibility property": there are traces that reach the end*)
   14.23 -Goal "\\<exists>X NB K. \\<exists>evs \\<in> yahalom.          \
   14.24 -\            Says A B {|X, Crypt K (Nonce NB)|} \\<in> set evs";
   14.25 -by (REPEAT (resolve_tac [exI,bexI] 1));
   14.26 -by (rtac (yahalom.Nil RS 
   14.27 -          yahalom.YM1 RS yahalom.Reception RS
   14.28 -          yahalom.YM2 RS yahalom.Reception RS 
   14.29 -          yahalom.YM3 RS yahalom.Reception RS yahalom.YM4) 2);
   14.30 -by possibility_tac;
   14.31 -result();
   14.32 -
   14.33 -Goal "[| Gets B X \\<in> set evs; evs \\<in> yahalom |] ==> \\<exists>A. Says A B X \\<in> set evs";
   14.34 -by (etac rev_mp 1);
   14.35 -by (etac yahalom.induct 1);
   14.36 -by Auto_tac;
   14.37 -qed "Gets_imp_Says";
   14.38 -
   14.39 -(*Must be proved separately for each protocol*)
   14.40 -Goal "[| Gets B X \\<in> set evs; evs \\<in> yahalom |]  ==> X \\<in> knows Spy evs";
   14.41 -by (blast_tac (claset() addSDs [Gets_imp_Says, Says_imp_knows_Spy]) 1);
   14.42 -qed"Gets_imp_knows_Spy";
   14.43 -AddDs [Gets_imp_knows_Spy RS parts.Inj];
   14.44 -
   14.45 -
   14.46 -(**** Inductive proofs about yahalom ****)
   14.47 -
   14.48 -(** For reasoning about the encrypted portion of messages **)
   14.49 -
   14.50 -(*Lets us treat YM4 using a similar argument as for the Fake case.*)
   14.51 -Goal "[| Gets A {|NB, Crypt (shrK A) Y, X|} \\<in> set evs;  evs \\<in> yahalom |]  \
   14.52 -\     ==> X \\<in> analz (knows Spy evs)";
   14.53 -by (blast_tac (claset() addSDs [Gets_imp_knows_Spy RS analz.Inj]) 1);
   14.54 -qed "YM4_analz_knows_Spy";
   14.55 -
   14.56 -bind_thm ("YM4_parts_knows_Spy",
   14.57 -          YM4_analz_knows_Spy RS (impOfSubs analz_subset_parts));
   14.58 -
   14.59 -(*For Oops*)
   14.60 -Goal "Says Server A {|NB, Crypt (shrK A) {|B,K,NA|}, X|} \\<in> set evs \
   14.61 -\     ==> K \\<in> parts (knows Spy evs)";
   14.62 -by (blast_tac (claset() addSDs [parts.Body, 
   14.63 -         Says_imp_knows_Spy RS parts.Inj]) 1);
   14.64 -qed "YM4_Key_parts_knows_Spy";
   14.65 -
   14.66 -(*For proving the easier theorems about X \\<notin> parts (knows Spy evs).*)
   14.67 -fun parts_knows_Spy_tac i = 
   14.68 -  EVERY
   14.69 -   [ftac YM4_Key_parts_knows_Spy (i+7),
   14.70 -    ftac YM4_parts_knows_Spy (i+6), assume_tac (i+6),
   14.71 -    prove_simple_subgoals_tac i];
   14.72 -
   14.73 -(*Induction for regularity theorems.  If induction formula has the form
   14.74 -   X \\<notin> analz (knows Spy evs) --> ... then it shortens the proof by discarding
   14.75 -   needless information about analz (insert X (knows Spy evs))  *)
   14.76 -fun parts_induct_tac i = 
   14.77 -    etac yahalom.induct i
   14.78 -    THEN 
   14.79 -    REPEAT (FIRSTGOAL analz_mono_contra_tac)
   14.80 -    THEN  parts_knows_Spy_tac i;
   14.81 -
   14.82 -
   14.83 -(** Theorems of the form X \\<notin> parts (knows Spy evs) imply that NOBODY
   14.84 -    sends messages containing X! **)
   14.85 -
   14.86 -(*Spy never sees another agent's shared key! (unless it's bad at start)*)
   14.87 -Goal "evs \\<in> yahalom ==> (Key (shrK A) \\<in> parts (knows Spy evs)) = (A \\<in> bad)";
   14.88 -by (parts_induct_tac 1);
   14.89 -by (ALLGOALS Blast_tac);
   14.90 -qed "Spy_see_shrK";
   14.91 -Addsimps [Spy_see_shrK];
   14.92 -
   14.93 -Goal "evs \\<in> yahalom ==> (Key (shrK A) \\<in> analz (knows Spy evs)) = (A \\<in> bad)";
   14.94 -by Auto_tac;
   14.95 -qed "Spy_analz_shrK";
   14.96 -Addsimps [Spy_analz_shrK];
   14.97 -
   14.98 -AddSDs [Spy_see_shrK RSN (2, rev_iffD1), 
   14.99 -	Spy_analz_shrK RSN (2, rev_iffD1)];
  14.100 -
  14.101 -
  14.102 -(*Nobody can have used non-existent keys!  Needed to apply analz_insert_Key*)
  14.103 -Goal "evs \\<in> yahalom ==>          \
  14.104 -\      Key K \\<notin> used evs --> K \\<notin> keysFor (parts (knows Spy evs))";
  14.105 -by (parts_induct_tac 1);
  14.106 -(*YM4: Key K is not fresh!*)
  14.107 -by (Blast_tac 3);
  14.108 -(*YM3*)
  14.109 -by (blast_tac (claset() addss (simpset())) 2);
  14.110 -(*Fake*)
  14.111 -by (blast_tac (claset() addSDs [keysFor_parts_insert]) 1);
  14.112 -qed_spec_mp "new_keys_not_used";
  14.113 -Addsimps [new_keys_not_used];
  14.114 -
  14.115 -(*Earlier, ALL protocol proofs declared this theorem.  
  14.116 -  But Yahalom and Kerberos IV are the only ones that need it!*)
  14.117 -bind_thm ("new_keys_not_analzd",
  14.118 -          [analz_subset_parts RS keysFor_mono,
  14.119 -           new_keys_not_used] MRS contra_subsetD);
  14.120 -
  14.121 -(*Describes the form of K when the Server sends this message.  Useful for
  14.122 -  Oops as well as main secrecy property.*)
  14.123 -Goal "[| Says Server A {|nb', Crypt (shrK A) {|Agent B, Key K, na|}, X|} \
  14.124 -\         \\<in> set evs;                                            \
  14.125 -\        evs \\<in> yahalom |]                                       \
  14.126 -\     ==> K \\<notin> range shrK";
  14.127 -by (etac rev_mp 1);
  14.128 -by (etac yahalom.induct 1);
  14.129 -by (ALLGOALS Asm_simp_tac);
  14.130 -qed "Says_Server_message_form";
  14.131 -
  14.132 -
  14.133 -(*For proofs involving analz.*)
  14.134 -val analz_knows_Spy_tac = 
  14.135 -    dtac YM4_analz_knows_Spy 7 THEN assume_tac 7 THEN
  14.136 -    ftac Says_Server_message_form 8 THEN
  14.137 -    assume_tac 8 THEN
  14.138 -    REPEAT ((etac conjE ORELSE' hyp_subst_tac) 8);
  14.139 -
  14.140 -
  14.141 -(****
  14.142 - The following is to prove theorems of the form
  14.143 -
  14.144 -          Key K \\<in> analz (insert (Key KAB) (knows Spy evs)) ==>
  14.145 -          Key K \\<in> analz (knows Spy evs)
  14.146 -
  14.147 - A more general formula must be proved inductively.
  14.148 -
  14.149 -****)
  14.150 -
  14.151 -(** Session keys are not used to encrypt other session keys **)
  14.152 -
  14.153 -Goal "evs \\<in> yahalom ==>                               \
  14.154 -\  \\<forall>K KK. KK <= - (range shrK) -->                 \
  14.155 -\         (Key K \\<in> analz (Key`KK Un (knows Spy evs))) =  \
  14.156 -\         (K \\<in> KK | Key K \\<in> analz (knows Spy evs))";
  14.157 -by (etac yahalom.induct 1);
  14.158 -by analz_knows_Spy_tac;
  14.159 -by (REPEAT_FIRST (resolve_tac [allI, impI]));
  14.160 -by (REPEAT_FIRST (rtac analz_image_freshK_lemma));
  14.161 -by (ALLGOALS (asm_simp_tac analz_image_freshK_ss));
  14.162 -(*Fake*) 
  14.163 -by (spy_analz_tac 1);
  14.164 -qed_spec_mp "analz_image_freshK";
  14.165 -
  14.166 -Goal "[| evs \\<in> yahalom;  KAB \\<notin> range shrK |] ==>     \
  14.167 -\     Key K \\<in> analz (insert (Key KAB) (knows Spy evs)) =  \
  14.168 -\     (K = KAB | Key K \\<in> analz (knows Spy evs))";
  14.169 -by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
  14.170 -qed "analz_insert_freshK";
  14.171 -
  14.172 -
  14.173 -(*** The Key K uniquely identifies the Server's  message. **)
  14.174 -
  14.175 -Goal "[| Says Server A                                            \
  14.176 -\         {|nb, Crypt (shrK A) {|Agent B, Key K, na|}, X|} \\<in> set evs; \
  14.177 -\       Says Server A'                                           \
  14.178 -\         {|nb', Crypt (shrK A') {|Agent B', Key K, na'|}, X'|} \\<in> set evs; \
  14.179 -\       evs \\<in> yahalom |]                                         \
  14.180 -\    ==> A=A' & B=B' & na=na' & nb=nb'";
  14.181 -by (etac rev_mp 1);
  14.182 -by (etac rev_mp 1);
  14.183 -by (etac yahalom.induct 1);
  14.184 -by (ALLGOALS Asm_simp_tac);
  14.185 -(*YM3, by freshness*)
  14.186 -by (Blast_tac 1);
  14.187 -qed "unique_session_keys";
  14.188 -
  14.189 -
  14.190 -(** Crucial secrecy property: Spy does not see the keys sent in msg YM3 **)
  14.191 -
  14.192 -Goal "[| A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]              \
  14.193 -\     ==> Says Server A                                      \
  14.194 -\           {|nb, Crypt (shrK A) {|Agent B, Key K, na|},     \
  14.195 -\                 Crypt (shrK B) {|Agent A, Agent B, Key K, nb|}|} \
  14.196 -\          \\<in> set evs -->                                     \
  14.197 -\         Notes Spy {|na, nb, Key K|} \\<notin> set evs -->         \
  14.198 -\         Key K \\<notin> analz (knows Spy evs)";
  14.199 -by (etac yahalom.induct 1);
  14.200 -by analz_knows_Spy_tac;
  14.201 -by (ALLGOALS
  14.202 -    (asm_simp_tac 
  14.203 -     (simpset() addsimps split_ifs
  14.204 -	        addsimps [new_keys_not_analzd, analz_insert_eq, 
  14.205 -                          analz_insert_freshK])));
  14.206 -(*Oops*)
  14.207 -by (blast_tac (claset() addDs [unique_session_keys]) 3);
  14.208 -(*YM3*)
  14.209 -by (Blast_tac 2);
  14.210 -(*Fake*) 
  14.211 -by (spy_analz_tac 1);
  14.212 -val lemma = result() RS mp RS mp RSN(2,rev_notE);
  14.213 -
  14.214 -
  14.215 -(*Final version*)
  14.216 -Goal "[| Says Server A                                    \
  14.217 -\           {|nb, Crypt (shrK A) {|Agent B, Key K, na|},  \
  14.218 -\                 Crypt (shrK B) {|Agent A, Agent B, Key K, nb|}|}    \
  14.219 -\        \\<in> set evs;                                       \
  14.220 -\        Notes Spy {|na, nb, Key K|} \\<notin> set evs;          \
  14.221 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]           \
  14.222 -\     ==> Key K \\<notin> analz (knows Spy evs)";
  14.223 -by (blast_tac (claset() addSEs [lemma] addDs [Says_Server_message_form]) 1);
  14.224 -qed "Spy_not_see_encrypted_key";
  14.225 -
  14.226 -
  14.227 -(** Security Guarantee for A upon receiving YM3 **)
  14.228 -
  14.229 -(*If the encrypted message appears then it originated with the Server.
  14.230 -  May now apply Spy_not_see_encrypted_key, subject to its conditions.*)
  14.231 -Goal "[| Crypt (shrK A) {|Agent B, Key K, na|}                      \
  14.232 -\         \\<in> parts (knows Spy evs);                                      \
  14.233 -\        A \\<notin> bad;  evs \\<in> yahalom |]                                \
  14.234 -\      ==> \\<exists>nb. Says Server A                                     \
  14.235 -\                   {|nb, Crypt (shrK A) {|Agent B, Key K, na|},    \
  14.236 -\                         Crypt (shrK B) {|Agent A, Agent B, Key K, nb|}|} \
  14.237 -\                 \\<in> set evs";
  14.238 -by (etac rev_mp 1);
  14.239 -by (parts_induct_tac 1);
  14.240 -by (ALLGOALS Blast_tac);
  14.241 -qed "A_trusts_YM3";
  14.242 -
  14.243 -(*The obvious combination of A_trusts_YM3 with Spy_not_see_encrypted_key*)
  14.244 -Goal "[| Crypt (shrK A) {|Agent B, Key K, na|} \\<in> parts (knows Spy evs); \
  14.245 -\        \\<forall>nb. Notes Spy {|na, nb, Key K|} \\<notin> set evs;            \
  14.246 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]                     \
  14.247 -\     ==> Key K \\<notin> analz (knows Spy evs)";
  14.248 -by (blast_tac (claset() addSDs [A_trusts_YM3, Spy_not_see_encrypted_key]) 1);
  14.249 -qed "A_gets_good_key";
  14.250 -
  14.251 -
  14.252 -(** Security Guarantee for B upon receiving YM4 **)
  14.253 -
  14.254 -(*B knows, by the first part of A's message, that the Server distributed 
  14.255 -  the key for A and B, and has associated it with NB.*)
  14.256 -Goal "[| Crypt (shrK B) {|Agent A, Agent B, Key K, Nonce NB|} \
  14.257 -\          \\<in> parts (knows Spy evs);                               \
  14.258 -\        B \\<notin> bad;  evs \\<in> yahalom |]                          \
  14.259 -\ ==> \\<exists>NA. Says Server A                                       \
  14.260 -\            {|Nonce NB,                                      \
  14.261 -\              Crypt (shrK A) {|Agent B, Key K, Nonce NA|},   \
  14.262 -\              Crypt (shrK B) {|Agent A, Agent B, Key K, Nonce NB|}|} \
  14.263 -\            \\<in> set evs";
  14.264 -by (etac rev_mp 1);
  14.265 -by (parts_induct_tac 1);
  14.266 -by (ALLGOALS Blast_tac);
  14.267 -qed "B_trusts_YM4_shrK";
  14.268 -
  14.269 -
  14.270 -(*With this protocol variant, we don't need the 2nd part of YM4 at all:
  14.271 -  Nonce NB is available in the first part.*)
  14.272 -
  14.273 -(*What can B deduce from receipt of YM4?  Stronger and simpler than Yahalom
  14.274 -  because we do not have to show that NB is secret. *)
  14.275 -Goal "[| Gets B {|Crypt (shrK B) {|Agent A, Agent B, Key K, Nonce NB|}, \
  14.276 -\                    X|}                                         \
  14.277 -\          \\<in> set evs;                                            \
  14.278 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]                  \
  14.279 -\ ==> \\<exists>NA. Says Server A                                          \
  14.280 -\            {|Nonce NB,                                         \
  14.281 -\              Crypt (shrK A) {|Agent B, Key K, Nonce NA|},      \
  14.282 -\              Crypt (shrK B) {|Agent A, Agent B, Key K, Nonce NB|}|} \
  14.283 -\           \\<in> set evs";
  14.284 -by (blast_tac (claset() addSDs [B_trusts_YM4_shrK]) 1);
  14.285 -qed "B_trusts_YM4";
  14.286 -
  14.287 -
  14.288 -(*The obvious combination of B_trusts_YM4 with Spy_not_see_encrypted_key*)
  14.289 -Goal "[| Gets B {|Crypt (shrK B) {|Agent A, Agent B, Key K, Nonce NB|}, \
  14.290 -\                    X|}                                         \
  14.291 -\          \\<in> set evs;                                            \
  14.292 -\        \\<forall>na. Notes Spy {|na, Nonce NB, Key K|} \\<notin> set evs;   \
  14.293 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]                  \
  14.294 -\     ==> Key K \\<notin> analz (knows Spy evs)";
  14.295 -by (blast_tac (claset() addSDs [B_trusts_YM4, Spy_not_see_encrypted_key]) 1);
  14.296 -qed "B_gets_good_key";
  14.297 -
  14.298 -
  14.299 -
  14.300 -(*** Authenticating B to A ***)
  14.301 -
  14.302 -(*The encryption in message YM2 tells us it cannot be faked.*)
  14.303 -Goal "[| Crypt (shrK B) {|Agent A, Nonce NA|} \\<in> parts (knows Spy evs);  \
  14.304 -\        B \\<notin> bad;  evs \\<in> yahalom                                   \
  14.305 -\     |] ==> \\<exists>NB. Says B Server {|Agent B, Nonce NB,              \
  14.306 -\                            Crypt (shrK B) {|Agent A, Nonce NA|}|} \
  14.307 -\                     \\<in> set evs";
  14.308 -by (etac rev_mp 1);
  14.309 -by (etac rev_mp 1);
  14.310 -by (parts_induct_tac 1);
  14.311 -by (ALLGOALS Blast_tac);
  14.312 -qed "B_Said_YM2";
  14.313 -
  14.314 -
  14.315 -(*If the server sends YM3 then B sent YM2, perhaps with a different NB*)
  14.316 -Goal "[| Says Server A                                              \
  14.317 -\            {|nb, Crypt (shrK A) {|Agent B, Key K, Nonce NA|}, X|} \
  14.318 -\          \\<in> set evs;                                               \
  14.319 -\        B \\<notin> bad;  evs \\<in> yahalom                                   \
  14.320 -\     |] ==> \\<exists>nb'. Says B Server {|Agent B, nb',                  \
  14.321 -\                            Crypt (shrK B) {|Agent A, Nonce NA|}|} \
  14.322 -\                      \\<in> set evs";
  14.323 -by (etac rev_mp 1);
  14.324 -by (etac rev_mp 1);
  14.325 -by (etac yahalom.induct 1);
  14.326 -by (ALLGOALS Asm_simp_tac);
  14.327 -(*YM3*)
  14.328 -by (blast_tac (claset() addSDs [B_Said_YM2]) 3);
  14.329 -(*Fake, YM2*)
  14.330 -by (ALLGOALS Blast_tac);
  14.331 -val lemma = result();
  14.332 -
  14.333 -(*If A receives YM3 then B has used nonce NA (and therefore is alive)*)
  14.334 -Goal "[| Gets A {|nb, Crypt (shrK A) {|Agent B, Key K, Nonce NA|}, X|}   \
  14.335 -\          \\<in> set evs;                                                    \
  14.336 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]                          \
  14.337 -\==> \\<exists>nb'. Says B Server                                               \
  14.338 -\                 {|Agent B, nb', Crypt (shrK B) {|Agent A, Nonce NA|}|} \
  14.339 -\              \\<in> set evs";
  14.340 -by (blast_tac (claset() addSDs [A_trusts_YM3, lemma]) 1);
  14.341 -qed "YM3_auth_B_to_A";
  14.342 -
  14.343 -
  14.344 -(*** Authenticating A to B using the certificate Crypt K (Nonce NB) ***)
  14.345 -
  14.346 -(*Assuming the session key is secure, if both certificates are present then
  14.347 -  A has said NB.  We can't be sure about the rest of A's message, but only
  14.348 -  NB matters for freshness.  Note that  Key K \\<notin> analz (knows Spy evs)  must be
  14.349 -  the FIRST antecedent of the induction formula.*)  
  14.350 -Goal "evs \\<in> yahalom                                     \
  14.351 -\     ==> Key K \\<notin> analz (knows Spy evs) -->                \
  14.352 -\         Crypt K (Nonce NB) \\<in> parts (knows Spy evs) -->    \
  14.353 -\         Crypt (shrK B) {|Agent A, Agent B, Key K, Nonce NB|}      \
  14.354 -\           \\<in> parts (knows Spy evs) -->                     \
  14.355 -\         B \\<notin> bad -->                                  \
  14.356 -\         (\\<exists>X. Says A B {|X, Crypt K (Nonce NB)|} \\<in> set evs)";
  14.357 -by (parts_induct_tac 1);
  14.358 -(*Fake*)
  14.359 -by (Blast_tac 1);
  14.360 -(*YM3: by new_keys_not_used we note that Crypt K (Nonce NB) could not exist*)
  14.361 -by (force_tac (claset() addSDs [Crypt_imp_keysFor], simpset()) 1); 
  14.362 -(*YM4: was Crypt K (Nonce NB) the very last message?  If not, use ind. hyp.*)
  14.363 -by (asm_simp_tac (simpset() addsimps [ex_disj_distrib]) 1);
  14.364 -(*Yes: apply unicity of session keys.  [Ind. hyp. no longer needed!]*)
  14.365 -by (blast_tac (claset() addSDs [Gets_imp_Says, A_trusts_YM3, B_trusts_YM4_shrK,
  14.366 -                                Crypt_Spy_analz_bad]
  14.367 -		addDs  [Says_imp_spies RS analz.Inj, unique_session_keys]) 1);
  14.368 -qed_spec_mp "Auth_A_to_B_lemma";
  14.369 -
  14.370 -
  14.371 -(*If B receives YM4 then A has used nonce NB (and therefore is alive).
  14.372 -  Moreover, A associates K with NB (thus is talking about the same run).
  14.373 -  Other premises guarantee secrecy of K.*)
  14.374 -Goal "[| Gets B {|Crypt (shrK B) {|Agent A, Agent B, Key K, Nonce NB|}, \
  14.375 -\                    Crypt K (Nonce NB)|} \\<in> set evs;                 \
  14.376 -\        (\\<forall>NA. Notes Spy {|Nonce NA, Nonce NB, Key K|} \\<notin> set evs); \
  14.377 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]                    \
  14.378 -\     ==> \\<exists>X. Says A B {|X, Crypt K (Nonce NB)|} \\<in> set evs";
  14.379 -by (blast_tac (claset() addIs [Auth_A_to_B_lemma]
  14.380 -                     addDs [Spy_not_see_encrypted_key, B_trusts_YM4_shrK]) 1);
  14.381 -qed_spec_mp "YM4_imp_A_Said_YM3";
    15.1 --- a/src/HOL/Auth/Yahalom2.thy	Wed Apr 11 11:53:54 2001 +0200
    15.2 +++ b/src/HOL/Auth/Yahalom2.thy	Thu Apr 12 12:45:05 2001 +0200
    15.3 @@ -13,64 +13,389 @@
    15.4    Proc. Royal Soc. 426 (1989)
    15.5  *)
    15.6  
    15.7 -Yahalom2 = Shared + 
    15.8 +theory Yahalom2 = Shared:
    15.9  
   15.10 -consts  yahalom   :: event list set
   15.11 +consts  yahalom   :: "event list set"
   15.12  inductive "yahalom"
   15.13 -  intrs 
   15.14 +  intros
   15.15           (*Initial trace is empty*)
   15.16 -    Nil  "[] \\<in> yahalom"
   15.17 +   Nil:  "[] \<in> yahalom"
   15.18  
   15.19           (*The spy MAY say anything he CAN say.  We do not expect him to
   15.20             invent new nonces here, but he can also use NS1.  Common to
   15.21             all similar protocols.*)
   15.22 -    Fake "[| evsf \\<in> yahalom;  X \\<in> synth (analz (knows Spy evsf)) |]
   15.23 -          ==> Says Spy B X  # evsf \\<in> yahalom"
   15.24 +   Fake: "[| evsf \<in> yahalom;  X \<in> synth (analz (knows Spy evsf)) |]
   15.25 +          ==> Says Spy B X  # evsf \<in> yahalom"
   15.26  
   15.27           (*A message that has been sent can be received by the
   15.28             intended recipient.*)
   15.29 -    Reception "[| evsr \\<in> yahalom;  Says A B X \\<in> set evsr |]
   15.30 -               ==> Gets B X # evsr \\<in> yahalom"
   15.31 +   Reception: "[| evsr \<in> yahalom;  Says A B X \<in> set evsr |]
   15.32 +               ==> Gets B X # evsr \<in> yahalom"
   15.33  
   15.34           (*Alice initiates a protocol run*)
   15.35 -    YM1  "[| evs1 \\<in> yahalom;  Nonce NA \\<notin> used evs1 |]
   15.36 -          ==> Says A B {|Agent A, Nonce NA|} # evs1 \\<in> yahalom"
   15.37 +   YM1:  "[| evs1 \<in> yahalom;  Nonce NA \<notin> used evs1 |]
   15.38 +          ==> Says A B {|Agent A, Nonce NA|} # evs1 \<in> yahalom"
   15.39  
   15.40           (*Bob's response to Alice's message.*)
   15.41 -    YM2  "[| evs2 \\<in> yahalom;  Nonce NB \\<notin> used evs2;
   15.42 -             Gets B {|Agent A, Nonce NA|} \\<in> set evs2 |]
   15.43 -          ==> Says B Server 
   15.44 +   YM2:  "[| evs2 \<in> yahalom;  Nonce NB \<notin> used evs2;
   15.45 +             Gets B {|Agent A, Nonce NA|} \<in> set evs2 |]
   15.46 +          ==> Says B Server
   15.47                    {|Agent B, Nonce NB, Crypt (shrK B) {|Agent A, Nonce NA|}|}
   15.48 -                # evs2 \\<in> yahalom"
   15.49 +                # evs2 \<in> yahalom"
   15.50  
   15.51           (*The Server receives Bob's message.  He responds by sending a
   15.52             new session key to Alice, with a certificate for forwarding to Bob.
   15.53             Both agents are quoted in the 2nd certificate to prevent attacks!*)
   15.54 -    YM3  "[| evs3 \\<in> yahalom;  Key KAB \\<notin> used evs3;
   15.55 +   YM3:  "[| evs3 \<in> yahalom;  Key KAB \<notin> used evs3;
   15.56               Gets Server {|Agent B, Nonce NB,
   15.57  			   Crypt (shrK B) {|Agent A, Nonce NA|}|}
   15.58 -               \\<in> set evs3 |]
   15.59 +               \<in> set evs3 |]
   15.60            ==> Says Server A
   15.61 -               {|Nonce NB, 
   15.62 +               {|Nonce NB,
   15.63                   Crypt (shrK A) {|Agent B, Key KAB, Nonce NA|},
   15.64                   Crypt (shrK B) {|Agent A, Agent B, Key KAB, Nonce NB|}|}
   15.65 -                 # evs3 \\<in> yahalom"
   15.66 +                 # evs3 \<in> yahalom"
   15.67  
   15.68           (*Alice receives the Server's (?) message, checks her Nonce, and
   15.69             uses the new session key to send Bob his Nonce.*)
   15.70 -    YM4  "[| evs4 \\<in> yahalom;  
   15.71 +   YM4:  "[| evs4 \<in> yahalom;
   15.72               Gets A {|Nonce NB, Crypt (shrK A) {|Agent B, Key K, Nonce NA|},
   15.73 -                      X|}  \\<in> set evs4;
   15.74 -             Says A B {|Agent A, Nonce NA|} \\<in> set evs4 |]
   15.75 -          ==> Says A B {|X, Crypt K (Nonce NB)|} # evs4 \\<in> yahalom"
   15.76 +                      X|}  \<in> set evs4;
   15.77 +             Says A B {|Agent A, Nonce NA|} \<in> set evs4 |]
   15.78 +          ==> Says A B {|X, Crypt K (Nonce NB)|} # evs4 \<in> yahalom"
   15.79  
   15.80           (*This message models possible leaks of session keys.  The nonces
   15.81             identify the protocol run.  Quoting Server here ensures they are
   15.82             correct. *)
   15.83 -    Oops "[| evso \\<in> yahalom;  
   15.84 -             Says Server A {|Nonce NB, 
   15.85 +   Oops: "[| evso \<in> yahalom;
   15.86 +             Says Server A {|Nonce NB,
   15.87                               Crypt (shrK A) {|Agent B, Key K, Nonce NA|},
   15.88 -                             X|}  \\<in> set evso |]
   15.89 -          ==> Notes Spy {|Nonce NA, Nonce NB, Key K|} # evso \\<in> yahalom"
   15.90 +                             X|}  \<in> set evso |]
   15.91 +          ==> Notes Spy {|Nonce NA, Nonce NB, Key K|} # evso \<in> yahalom"
   15.92 +
   15.93 +
   15.94 +declare Says_imp_knows_Spy [THEN analz.Inj, dest]
   15.95 +declare parts.Body  [dest]
   15.96 +declare Fake_parts_insert_in_Un  [dest]
   15.97 +declare analz_into_parts [dest]
   15.98 +
   15.99 +(*A "possibility property": there are traces that reach the end*)
  15.100 +lemma "\<exists>X NB K. \<exists>evs \<in> yahalom.
  15.101 +             Says A B {|X, Crypt K (Nonce NB)|} \<in> set evs"
  15.102 +apply (intro exI bexI)
  15.103 +apply (rule_tac [2] yahalom.Nil
  15.104 +                    [THEN yahalom.YM1, THEN yahalom.Reception,
  15.105 +                     THEN yahalom.YM2, THEN yahalom.Reception,
  15.106 +                     THEN yahalom.YM3, THEN yahalom.Reception,
  15.107 +                     THEN yahalom.YM4])
  15.108 +apply possibility
  15.109 +done
  15.110 +
  15.111 +lemma Gets_imp_Says:
  15.112 +     "[| Gets B X \<in> set evs; evs \<in> yahalom |] ==> \<exists>A. Says A B X \<in> set evs"
  15.113 +by (erule rev_mp, erule yahalom.induct, auto)
  15.114 +
  15.115 +(*Must be proved separately for each protocol*)
  15.116 +lemma Gets_imp_knows_Spy:
  15.117 +     "[| Gets B X \<in> set evs; evs \<in> yahalom |]  ==> X \<in> knows Spy evs"
  15.118 +by (blast dest!: Gets_imp_Says Says_imp_knows_Spy)
  15.119 +
  15.120 +declare Gets_imp_knows_Spy [THEN analz.Inj, dest]
  15.121 +
  15.122 +
  15.123 +(**** Inductive proofs about yahalom ****)
  15.124 +
  15.125 +(** For reasoning about the encrypted portion of messages **)
  15.126 +
  15.127 +(*Lets us treat YM4 using a similar argument as for the Fake case.*)
  15.128 +lemma YM4_analz_knows_Spy:
  15.129 +     "[| Gets A {|NB, Crypt (shrK A) Y, X|} \<in> set evs;  evs \<in> yahalom |]
  15.130 +      ==> X \<in> analz (knows Spy evs)"
  15.131 +by blast
  15.132 +
  15.133 +lemmas YM4_parts_knows_Spy =
  15.134 +       YM4_analz_knows_Spy [THEN analz_into_parts, standard]
  15.135 +
  15.136 +
  15.137 +(** Theorems of the form X \<notin> parts (knows Spy evs) imply that NOBODY
  15.138 +    sends messages containing X! **)
  15.139 +
  15.140 +(*Spy never sees a good agent's shared key!*)
  15.141 +lemma Spy_see_shrK [simp]:
  15.142 +     "evs \<in> yahalom ==> (Key (shrK A) \<in> parts (knows Spy evs)) = (A \<in> bad)"
  15.143 +apply (erule yahalom.induct, force,
  15.144 +       drule_tac [6] YM4_parts_knows_Spy, simp_all)
  15.145 +apply blast+
  15.146 +done
  15.147 +
  15.148 +lemma Spy_analz_shrK [simp]:
  15.149 +     "evs \<in> yahalom ==> (Key (shrK A) \<in> analz (knows Spy evs)) = (A \<in> bad)"
  15.150 +by auto
  15.151 +
  15.152 +lemma Spy_see_shrK_D [dest!]:
  15.153 +     "[|Key (shrK A) \<in> parts (knows Spy evs);  evs \<in> yahalom|] ==> A \<in> bad"
  15.154 +by (blast dest: Spy_see_shrK)
  15.155 +
  15.156 +(*Nobody can have used non-existent keys!  Needed to apply analz_insert_Key*)
  15.157 +lemma new_keys_not_used [rule_format, simp]:
  15.158 + "evs \<in> yahalom ==> Key K \<notin> used evs --> K \<notin> keysFor (parts (knows Spy evs))"
  15.159 +apply (erule yahalom.induct, force,
  15.160 +       frule_tac [6] YM4_parts_knows_Spy, simp_all)
  15.161 +(*Fake, YM3, YM4*)
  15.162 +apply (blast dest!: keysFor_parts_insert)+
  15.163 +done
  15.164 +
  15.165 +
  15.166 +(*Describes the form of K when the Server sends this message.  Useful for
  15.167 +  Oops as well as main secrecy property.*)
  15.168 +lemma Says_Server_message_form:
  15.169 +     "[| Says Server A {|nb', Crypt (shrK A) {|Agent B, Key K, na|}, X|}
  15.170 +          \<in> set evs;  evs \<in> yahalom |]
  15.171 +      ==> K \<notin> range shrK"
  15.172 +by (erule rev_mp, erule yahalom.induct, simp_all)
  15.173 +
  15.174 +
  15.175 +(****
  15.176 + The following is to prove theorems of the form
  15.177 +
  15.178 +          Key K \<in> analz (insert (Key KAB) (knows Spy evs)) ==>
  15.179 +          Key K \<in> analz (knows Spy evs)
  15.180 +
  15.181 + A more general formula must be proved inductively.
  15.182 +****)
  15.183 +
  15.184 +(** Session keys are not used to encrypt other session keys **)
  15.185 +
  15.186 +lemma analz_image_freshK [rule_format]:
  15.187 + "evs \<in> yahalom ==>
  15.188 +   \<forall>K KK. KK <= - (range shrK) -->
  15.189 +          (Key K \<in> analz (Key`KK Un (knows Spy evs))) =
  15.190 +          (K \<in> KK | Key K \<in> analz (knows Spy evs))"
  15.191 +apply (erule yahalom.induct, force, frule_tac [7] Says_Server_message_form,
  15.192 +       drule_tac [6] YM4_analz_knows_Spy)
  15.193 +apply analz_freshK
  15.194 +apply spy_analz
  15.195 +done
  15.196 +
  15.197 +lemma analz_insert_freshK:
  15.198 +     "[| evs \<in> yahalom;  KAB \<notin> range shrK |] ==>
  15.199 +      Key K \<in> analz (insert (Key KAB) (knows Spy evs)) =
  15.200 +      (K = KAB | Key K \<in> analz (knows Spy evs))"
  15.201 +by (simp only: analz_image_freshK analz_image_freshK_simps)
  15.202 +
  15.203 +
  15.204 +(*** The Key K uniquely identifies the Server's  message. **)
  15.205 +
  15.206 +lemma unique_session_keys:
  15.207 +     "[| Says Server A
  15.208 +          {|nb, Crypt (shrK A) {|Agent B, Key K, na|}, X|} \<in> set evs;
  15.209 +        Says Server A'
  15.210 +          {|nb', Crypt (shrK A') {|Agent B', Key K, na'|}, X'|} \<in> set evs;
  15.211 +        evs \<in> yahalom |]
  15.212 +     ==> A=A' & B=B' & na=na' & nb=nb'"
  15.213 +apply (erule rev_mp, erule rev_mp)
  15.214 +apply (erule yahalom.induct, simp_all)
  15.215 +(*YM3, by freshness*)
  15.216 +apply blast
  15.217 +done
  15.218 +
  15.219 +
  15.220 +(** Crucial secrecy property: Spy does not see the keys sent in msg YM3 **)
  15.221 +
  15.222 +lemma secrecy_lemma:
  15.223 +     "[| A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]
  15.224 +      ==> Says Server A
  15.225 +            {|nb, Crypt (shrK A) {|Agent B, Key K, na|},
  15.226 +                  Crypt (shrK B) {|Agent A, Agent B, Key K, nb|}|}
  15.227 +           \<in> set evs -->
  15.228 +          Notes Spy {|na, nb, Key K|} \<notin> set evs -->
  15.229 +          Key K \<notin> analz (knows Spy evs)"
  15.230 +apply (erule yahalom.induct, force, frule_tac [7] Says_Server_message_form,
  15.231 +       drule_tac [6] YM4_analz_knows_Spy)
  15.232 +apply (simp_all add: pushes analz_insert_eq analz_insert_freshK)
  15.233 +apply spy_analz  (*Fake*)
  15.234 +apply (blast dest: unique_session_keys)+  (*YM3, Oops*)
  15.235 +done
  15.236 +
  15.237 +
  15.238 +(*Final version*)
  15.239 +lemma Spy_not_see_encrypted_key:
  15.240 +     "[| Says Server A
  15.241 +            {|nb, Crypt (shrK A) {|Agent B, Key K, na|},
  15.242 +                  Crypt (shrK B) {|Agent A, Agent B, Key K, nb|}|}
  15.243 +         \<in> set evs;
  15.244 +         Notes Spy {|na, nb, Key K|} \<notin> set evs;
  15.245 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]
  15.246 +      ==> Key K \<notin> analz (knows Spy evs)"
  15.247 +by (blast dest: secrecy_lemma Says_Server_message_form)
  15.248 +
  15.249 +
  15.250 +(** Security Guarantee for A upon receiving YM3 **)
  15.251 +
  15.252 +(*If the encrypted message appears then it originated with the Server.
  15.253 +  May now apply Spy_not_see_encrypted_key, subject to its conditions.*)
  15.254 +lemma A_trusts_YM3:
  15.255 +     "[| Crypt (shrK A) {|Agent B, Key K, na|} \<in> parts (knows Spy evs);
  15.256 +         A \<notin> bad;  evs \<in> yahalom |]
  15.257 +      ==> \<exists>nb. Says Server A
  15.258 +                    {|nb, Crypt (shrK A) {|Agent B, Key K, na|},
  15.259 +                          Crypt (shrK B) {|Agent A, Agent B, Key K, nb|}|}
  15.260 +                  \<in> set evs"
  15.261 +apply (erule rev_mp)
  15.262 +apply (erule yahalom.induct, force,
  15.263 +       frule_tac [6] YM4_parts_knows_Spy, simp_all)
  15.264 +(*Fake, YM3*)
  15.265 +apply blast+
  15.266 +done
  15.267 +
  15.268 +(*The obvious combination of A_trusts_YM3 with Spy_not_see_encrypted_key*)
  15.269 +lemma A_gets_good_key:
  15.270 +     "[| Crypt (shrK A) {|Agent B, Key K, na|} \<in> parts (knows Spy evs);
  15.271 +         \<forall>nb. Notes Spy {|na, nb, Key K|} \<notin> set evs;
  15.272 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]
  15.273 +      ==> Key K \<notin> analz (knows Spy evs)"
  15.274 +by (blast dest!: A_trusts_YM3 Spy_not_see_encrypted_key)
  15.275 +
  15.276 +
  15.277 +(** Security Guarantee for B upon receiving YM4 **)
  15.278 +
  15.279 +(*B knows, by the first part of A's message, that the Server distributed
  15.280 +  the key for A and B, and has associated it with NB.*)
  15.281 +lemma B_trusts_YM4_shrK:
  15.282 +     "[| Crypt (shrK B) {|Agent A, Agent B, Key K, Nonce NB|}
  15.283 +           \<in> parts (knows Spy evs);
  15.284 +         B \<notin> bad;  evs \<in> yahalom |]
  15.285 +  ==> \<exists>NA. Says Server A
  15.286 +             {|Nonce NB,
  15.287 +               Crypt (shrK A) {|Agent B, Key K, Nonce NA|},
  15.288 +               Crypt (shrK B) {|Agent A, Agent B, Key K, Nonce NB|}|}
  15.289 +             \<in> set evs"
  15.290 +apply (erule rev_mp)
  15.291 +apply (erule yahalom.induct, force,
  15.292 +       frule_tac [6] YM4_parts_knows_Spy, simp_all)
  15.293 +(*Fake, YM3*)
  15.294 +apply blast+
  15.295 +done
  15.296 +
  15.297 +
  15.298 +(*With this protocol variant, we don't need the 2nd part of YM4 at all:
  15.299 +  Nonce NB is available in the first part.*)
  15.300 +
  15.301 +(*What can B deduce from receipt of YM4?  Stronger and simpler than Yahalom
  15.302 +  because we do not have to show that NB is secret. *)
  15.303 +lemma B_trusts_YM4:
  15.304 +     "[| Gets B {|Crypt (shrK B) {|Agent A, Agent B, Key K, Nonce NB|},  X|}
  15.305 +           \<in> set evs;
  15.306 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]
  15.307 +  ==> \<exists>NA. Says Server A
  15.308 +             {|Nonce NB,
  15.309 +               Crypt (shrK A) {|Agent B, Key K, Nonce NA|},
  15.310 +               Crypt (shrK B) {|Agent A, Agent B, Key K, Nonce NB|}|}
  15.311 +            \<in> set evs"
  15.312 +by (blast dest!: B_trusts_YM4_shrK)
  15.313 +
  15.314 +
  15.315 +(*The obvious combination of B_trusts_YM4 with Spy_not_see_encrypted_key*)
  15.316 +lemma B_gets_good_key:
  15.317 +     "[| Gets B {|Crypt (shrK B) {|Agent A, Agent B, Key K, Nonce NB|}, X|}
  15.318 +           \<in> set evs;
  15.319 +         \<forall>na. Notes Spy {|na, Nonce NB, Key K|} \<notin> set evs;
  15.320 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]
  15.321 +      ==> Key K \<notin> analz (knows Spy evs)"
  15.322 +by (blast dest!: B_trusts_YM4 Spy_not_see_encrypted_key)
  15.323 +
  15.324 +
  15.325 +(*** Authenticating B to A ***)
  15.326 +
  15.327 +(*The encryption in message YM2 tells us it cannot be faked.*)
  15.328 +lemma B_Said_YM2:
  15.329 +     "[| Crypt (shrK B) {|Agent A, Nonce NA|} \<in> parts (knows Spy evs);
  15.330 +         B \<notin> bad;  evs \<in> yahalom |]
  15.331 +      ==> \<exists>NB. Says B Server {|Agent B, Nonce NB,
  15.332 +                               Crypt (shrK B) {|Agent A, Nonce NA|}|}
  15.333 +                      \<in> set evs"
  15.334 +apply (erule rev_mp)
  15.335 +apply (erule yahalom.induct, force,
  15.336 +       frule_tac [6] YM4_parts_knows_Spy, simp_all)
  15.337 +(*Fake, YM2*)
  15.338 +apply blast+
  15.339 +done
  15.340 +
  15.341 +
  15.342 +(*If the server sends YM3 then B sent YM2, perhaps with a different NB*)
  15.343 +lemma YM3_auth_B_to_A_lemma:
  15.344 +     "[| Says Server A {|nb, Crypt (shrK A) {|Agent B, Key K, Nonce NA|}, X|}
  15.345 +           \<in> set evs;
  15.346 +         B \<notin> bad;  evs \<in> yahalom |]
  15.347 +      ==> \<exists>nb'. Says B Server {|Agent B, nb',
  15.348 +                                   Crypt (shrK B) {|Agent A, Nonce NA|}|}
  15.349 +                       \<in> set evs"
  15.350 +apply (erule rev_mp)
  15.351 +apply (erule yahalom.induct, simp_all)
  15.352 +(*Fake, YM2, YM3*)
  15.353 +apply (blast dest!: B_Said_YM2)+
  15.354 +done
  15.355 +
  15.356 +(*If A receives YM3 then B has used nonce NA (and therefore is alive)*)
  15.357 +lemma YM3_auth_B_to_A:
  15.358 +     "[| Gets A {|nb, Crypt (shrK A) {|Agent B, Key K, Nonce NA|}, X|}
  15.359 +           \<in> set evs;
  15.360 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]
  15.361 + ==> \<exists>nb'. Says B Server
  15.362 +                  {|Agent B, nb', Crypt (shrK B) {|Agent A, Nonce NA|}|}
  15.363 +               \<in> set evs"
  15.364 +by (blast dest!: A_trusts_YM3 YM3_auth_B_to_A_lemma)
  15.365 +
  15.366 +
  15.367 +
  15.368 +(*** Authenticating A to B using the certificate Crypt K (Nonce NB) ***)
  15.369 +
  15.370 +(*Assuming the session key is secure, if both certificates are present then
  15.371 +  A has said NB.  We can't be sure about the rest of A's message, but only
  15.372 +  NB matters for freshness.  Note that  Key K \<notin> analz (knows Spy evs)  must be
  15.373 +  the FIRST antecedent of the induction formula.*)
  15.374 +
  15.375 +(*This lemma allows a use of unique_session_keys in the next proof,
  15.376 +  which otherwise is extremely slow.*)
  15.377 +lemma secure_unique_session_keys:
  15.378 +     "[| Crypt (shrK A) {|Agent B, Key K, na|} \<in> analz (spies evs);
  15.379 +         Crypt (shrK A') {|Agent B', Key K, na'|} \<in> analz (spies evs);
  15.380 +         Key K \<notin> analz (knows Spy evs);  evs \<in> yahalom |]
  15.381 +     ==> A=A' & B=B'"
  15.382 +by (blast dest!: A_trusts_YM3 dest: unique_session_keys Crypt_Spy_analz_bad)
  15.383 +
  15.384 +
  15.385 +lemma Auth_A_to_B_lemma [rule_format]:
  15.386 +     "evs \<in> yahalom
  15.387 +      ==> Key K \<notin> analz (knows Spy evs) -->
  15.388 +          Crypt K (Nonce NB) \<in> parts (knows Spy evs) -->
  15.389 +          Crypt (shrK B) {|Agent A, Agent B, Key K, Nonce NB|}
  15.390 +            \<in> parts (knows Spy evs) -->
  15.391 +          B \<notin> bad -->
  15.392 +          (\<exists>X. Says A B {|X, Crypt K (Nonce NB)|} \<in> set evs)"
  15.393 +apply (erule yahalom.induct, force,
  15.394 +       frule_tac [6] YM4_parts_knows_Spy)
  15.395 +apply (analz_mono_contra, simp_all)
  15.396 +(*Fake*)
  15.397 +apply blast
  15.398 +(*YM3: by new_keys_not_used we note that Crypt K (Nonce NB) could not exist*)
  15.399 +apply (force dest!: Crypt_imp_keysFor)
  15.400 +(*YM4: was Crypt K (Nonce NB) the very last message?  If so, apply unicity
  15.401 +  of session keys; if not, use ind. hyp.*)
  15.402 +apply (blast dest!: B_trusts_YM4_shrK dest: secure_unique_session_keys  )
  15.403 +done
  15.404 +
  15.405 +
  15.406 +(*If B receives YM4 then A has used nonce NB (and therefore is alive).
  15.407 +  Moreover, A associates K with NB (thus is talking about the same run).
  15.408 +  Other premises guarantee secrecy of K.*)
  15.409 +lemma YM4_imp_A_Said_YM3 [rule_format]:
  15.410 +     "[| Gets B {|Crypt (shrK B) {|Agent A, Agent B, Key K, Nonce NB|},
  15.411 +                  Crypt K (Nonce NB)|} \<in> set evs;
  15.412 +         (\<forall>NA. Notes Spy {|Nonce NA, Nonce NB, Key K|} \<notin> set evs);
  15.413 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]
  15.414 +      ==> \<exists>X. Says A B {|X, Crypt K (Nonce NB)|} \<in> set evs"
  15.415 +by (blast intro: Auth_A_to_B_lemma
  15.416 +          dest: Spy_not_see_encrypted_key B_trusts_YM4_shrK)
  15.417  
  15.418  end
    16.1 --- a/src/HOL/Auth/Yahalom_Bad.ML	Wed Apr 11 11:53:54 2001 +0200
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,329 +0,0 @@
    16.4 -(*  Title:      HOL/Auth/Yahalom
    16.5 -    ID:         $Id$
    16.6 -    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
    16.7 -    Copyright   1996  University of Cambridge
    16.8 -
    16.9 -Inductive relation "yahalom" for the Yahalom protocol.
   16.10 -
   16.11 -From page 257 of
   16.12 -  Burrows, Abadi and Needham.  A Logic of Authentication.
   16.13 -  Proc. Royal Soc. 426 (1989)
   16.14 -*)
   16.15 -
   16.16 -(*A "possibility property": there are traces that reach the end*)
   16.17 -Goal "A \\<noteq> Server \
   16.18 -\     ==> \\<exists>X NB K. \\<exists>evs \\<in> yahalom.          \
   16.19 -\            Says A B {|X, Crypt K (Nonce NB)|} \\<in> set evs";
   16.20 -by (REPEAT (resolve_tac [exI,bexI] 1));
   16.21 -by (rtac (yahalom.Nil RS 
   16.22 -          yahalom.YM1 RS yahalom.Reception RS
   16.23 -          yahalom.YM2 RS yahalom.Reception RS 
   16.24 -          yahalom.YM3 RS yahalom.Reception RS yahalom.YM4) 2);
   16.25 -by possibility_tac;
   16.26 -result();
   16.27 -
   16.28 -Goal "[| Gets B X \\<in> set evs; evs \\<in> yahalom |] ==> \\<exists>A. Says A B X \\<in> set evs";
   16.29 -by (etac rev_mp 1);
   16.30 -by (etac yahalom.induct 1);
   16.31 -by Auto_tac;
   16.32 -qed "Gets_imp_Says";
   16.33 -
   16.34 -(*Must be proved separately for each protocol*)
   16.35 -Goal "[| Gets B X \\<in> set evs; evs \\<in> yahalom |]  ==> X \\<in> knows Spy evs";
   16.36 -by (blast_tac (claset() addSDs [Gets_imp_Says, Says_imp_knows_Spy]) 1);
   16.37 -qed"Gets_imp_knows_Spy";
   16.38 -AddDs [Gets_imp_knows_Spy RS parts.Inj];
   16.39 -
   16.40 -
   16.41 -(**** Inductive proofs about yahalom ****)
   16.42 -
   16.43 -
   16.44 -(** For reasoning about the encrypted portion of messages **)
   16.45 -
   16.46 -(*Lets us treat YM4 using a similar argument as for the Fake case.*)
   16.47 -Goal "[| Gets A {|Crypt (shrK A) Y, X|} \\<in> set evs;  evs \\<in> yahalom |]  \
   16.48 -\     ==> X \\<in> analz (knows Spy evs)";
   16.49 -by (blast_tac (claset() addSDs [Gets_imp_knows_Spy RS analz.Inj]) 1);
   16.50 -qed "YM4_analz_knows_Spy";
   16.51 -
   16.52 -bind_thm ("YM4_parts_knows_Spy",
   16.53 -          YM4_analz_knows_Spy RS (impOfSubs analz_subset_parts));
   16.54 -
   16.55 -(*For proving the easier theorems about X \\<notin> parts (knows Spy evs).*)
   16.56 -fun parts_knows_Spy_tac i = 
   16.57 -  EVERY
   16.58 -   [ftac YM4_parts_knows_Spy (i+6), assume_tac (i+6),
   16.59 -    prove_simple_subgoals_tac i];
   16.60 -
   16.61 -(*Induction for regularity theorems.  If induction formula has the form
   16.62 -   X \\<notin> analz (knows Spy evs) --> ... then it shortens the proof by discarding
   16.63 -   needless information about analz (insert X (knows Spy evs))  *)
   16.64 -fun parts_induct_tac i = 
   16.65 -    etac yahalom.induct i
   16.66 -    THEN 
   16.67 -    REPEAT (FIRSTGOAL analz_mono_contra_tac)
   16.68 -    THEN  parts_knows_Spy_tac i;
   16.69 -
   16.70 -
   16.71 -(** Theorems of the form X \\<notin> parts (knows Spy evs) imply that NOBODY
   16.72 -    sends messages containing X! **)
   16.73 -
   16.74 -(*Spy never sees another agent's shared key! (unless it's bad at start)*)
   16.75 -Goal "evs \\<in> yahalom ==> (Key (shrK A) \\<in> parts (knows Spy evs)) = (A \\<in> bad)";
   16.76 -by (parts_induct_tac 1);
   16.77 -by (Fake_parts_insert_tac 1);
   16.78 -by (ALLGOALS Blast_tac);
   16.79 -qed "Spy_see_shrK";
   16.80 -Addsimps [Spy_see_shrK];
   16.81 -
   16.82 -Goal "evs \\<in> yahalom ==> (Key (shrK A) \\<in> analz (knows Spy evs)) = (A \\<in> bad)";
   16.83 -by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset()));
   16.84 -qed "Spy_analz_shrK";
   16.85 -Addsimps [Spy_analz_shrK];
   16.86 -
   16.87 -AddSDs [Spy_see_shrK RSN (2, rev_iffD1), 
   16.88 -	Spy_analz_shrK RSN (2, rev_iffD1)];
   16.89 -
   16.90 -
   16.91 -(*Nobody can have used non-existent keys!  Needed to apply analz_insert_Key*)
   16.92 -Goal "evs \\<in> yahalom ==>          \
   16.93 -\      Key K \\<notin> used evs --> K \\<notin> keysFor (parts (knows Spy evs))";
   16.94 -by (parts_induct_tac 1);
   16.95 -(*Fake*)
   16.96 -by (blast_tac (claset() addSDs [keysFor_parts_insert]) 1);
   16.97 -(*YM2-4: Because Key K is not fresh, etc.*)
   16.98 -by (REPEAT (blast_tac (claset() addSEs knows_Spy_partsEs) 1));
   16.99 -qed_spec_mp "new_keys_not_used";
  16.100 -Addsimps [new_keys_not_used];
  16.101 -
  16.102 -
  16.103 -(*For proofs involving analz.*)
  16.104 -val analz_knows_Spy_tac = 
  16.105 -    ftac YM4_analz_knows_Spy 7 THEN assume_tac 7;
  16.106 -
  16.107 -(****
  16.108 - The following is to prove theorems of the form
  16.109 -
  16.110 -  Key K \\<in> analz (insert (Key KAB) (knows Spy evs)) ==>
  16.111 -  Key K \\<in> analz (knows Spy evs)
  16.112 -
  16.113 - A more general formula must be proved inductively.
  16.114 -****)
  16.115 -
  16.116 -(** Session keys are not used to encrypt other session keys **)
  16.117 -
  16.118 -Goal "evs \\<in> yahalom ==>                              \
  16.119 -\  \\<forall>K KK. KK <= - (range shrK) -->                \
  16.120 -\         (Key K \\<in> analz (Key`KK Un (knows Spy evs))) = \
  16.121 -\         (K \\<in> KK | Key K \\<in> analz (knows Spy evs))";
  16.122 -by (etac yahalom.induct 1);
  16.123 -by analz_knows_Spy_tac;
  16.124 -by (REPEAT_FIRST (resolve_tac [allI, impI]));
  16.125 -by (REPEAT_FIRST (rtac analz_image_freshK_lemma));
  16.126 -by (ALLGOALS (asm_simp_tac analz_image_freshK_ss));
  16.127 -(*Fake*) 
  16.128 -by (spy_analz_tac 1);
  16.129 -qed_spec_mp "analz_image_freshK";
  16.130 -
  16.131 -Goal "[| evs \\<in> yahalom;  KAB \\<notin> range shrK |]                  \
  16.132 -\      ==> Key K \\<in> analz (insert (Key KAB) (knows Spy evs)) =  \
  16.133 -\          (K = KAB | Key K \\<in> analz (knows Spy evs))";
  16.134 -by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
  16.135 -qed "analz_insert_freshK";
  16.136 -
  16.137 -
  16.138 -(*** The Key K uniquely identifies the Server's  message. **)
  16.139 -
  16.140 -Goal "[| Says Server A                                                 \
  16.141 -\         {|Crypt (shrK A) {|Agent B, Key K, na, nb|}, X|} \\<in> set evs;  \
  16.142 -\       Says Server A'                                                 \
  16.143 -\         {|Crypt (shrK A') {|Agent B', Key K, na', nb'|}, X'|} \\<in> set evs; \
  16.144 -\       evs \\<in> yahalom |]                                    \
  16.145 -\    ==> A=A' & B=B' & na=na' & nb=nb'";
  16.146 -by (etac rev_mp 1);
  16.147 -by (etac rev_mp 1);
  16.148 -by (etac yahalom.induct 1);
  16.149 -by (ALLGOALS Asm_simp_tac);
  16.150 -(*YM4*)
  16.151 -by (Blast_tac 2);
  16.152 -(*YM3, by freshness*)
  16.153 -by (blast_tac (claset() addSEs knows_Spy_partsEs) 1);
  16.154 -qed "unique_session_keys";
  16.155 -
  16.156 -
  16.157 -(** Crucial secrecy property: Spy does not see the keys sent in msg YM3 **)
  16.158 -
  16.159 -Goal "[| A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]                \
  16.160 -\     ==> Says Server A                                        \
  16.161 -\           {|Crypt (shrK A) {|Agent B, Key K, na, nb|},       \
  16.162 -\             Crypt (shrK B) {|Agent A, Key K|}|}              \
  16.163 -\          \\<in> set evs -->                                       \
  16.164 -\         Key K \\<notin> analz (knows Spy evs)";
  16.165 -by (etac yahalom.induct 1);
  16.166 -by analz_knows_Spy_tac;
  16.167 -by (ALLGOALS
  16.168 -    (asm_simp_tac 
  16.169 -     (simpset() addsimps split_ifs @ pushes @
  16.170 -                         [analz_insert_eq, analz_insert_freshK])));
  16.171 -(*YM3*)
  16.172 -by (blast_tac (claset() delrules [impCE]
  16.173 -                        addSEs knows_Spy_partsEs
  16.174 -                        addIs [impOfSubs analz_subset_parts]) 2);
  16.175 -(*Fake*) 
  16.176 -by (spy_analz_tac 1);
  16.177 -val lemma = result() RS mp RSN(2,rev_notE);
  16.178 -
  16.179 -
  16.180 -(*Final version*)
  16.181 -Goal "[| Says Server A                                         \
  16.182 -\           {|Crypt (shrK A) {|Agent B, Key K, na, nb|},       \
  16.183 -\             Crypt (shrK B) {|Agent A, Key K|}|}              \
  16.184 -\          \\<in> set evs;                                          \
  16.185 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]                \
  16.186 -\     ==> Key K \\<notin> analz (knows Spy evs)";
  16.187 -by (blast_tac (claset() addSEs [lemma]) 1);
  16.188 -qed "Spy_not_see_encrypted_key";
  16.189 -
  16.190 -
  16.191 -(** Security Guarantee for A upon receiving YM3 **)
  16.192 -
  16.193 -(*If the encrypted message appears then it originated with the Server*)
  16.194 -Goal "[| Crypt (shrK A) {|Agent B, Key K, na, nb|} \\<in> parts (knows Spy evs); \
  16.195 -\        A \\<notin> bad;  evs \\<in> yahalom |]                          \
  16.196 -\      ==> Says Server A                                      \
  16.197 -\           {|Crypt (shrK A) {|Agent B, Key K, na, nb|},      \
  16.198 -\             Crypt (shrK B) {|Agent A, Key K|}|}             \
  16.199 -\          \\<in> set evs";
  16.200 -by (etac rev_mp 1);
  16.201 -by (parts_induct_tac 1);
  16.202 -by (Fake_parts_insert_tac 1);
  16.203 -qed "A_trusts_YM3";
  16.204 -
  16.205 -(*The obvious combination of A_trusts_YM3 with Spy_not_see_encrypted_key*)
  16.206 -Goal "[| Crypt (shrK A) {|Agent B, Key K, na, nb|} \\<in> parts (knows Spy evs); \
  16.207 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]                \
  16.208 -\     ==> Key K \\<notin> analz (knows Spy evs)";
  16.209 -by (blast_tac (claset() addSDs [A_trusts_YM3, Spy_not_see_encrypted_key]) 1);
  16.210 -qed "A_gets_good_key";
  16.211 -
  16.212 -(** Security Guarantees for B upon receiving YM4 **)
  16.213 -
  16.214 -(*B knows, by the first part of A's message, that the Server distributed 
  16.215 -  the key for A and B.  But this part says nothing about nonces.*)
  16.216 -Goal "[| Crypt (shrK B) {|Agent A, Key K|} \\<in> parts (knows Spy evs);  \
  16.217 -\        B \\<notin> bad;  evs \\<in> yahalom |]                                 \
  16.218 -\     ==> \\<exists>NA NB. Says Server A                                    \
  16.219 -\                     {|Crypt (shrK A) {|Agent B, Key K,             \
  16.220 -\                                        Nonce NA, Nonce NB|},       \
  16.221 -\                       Crypt (shrK B) {|Agent A, Key K|}|}          \
  16.222 -\                    \\<in> set evs";
  16.223 -by (etac rev_mp 1);
  16.224 -by (parts_induct_tac 1);
  16.225 -by (Fake_parts_insert_tac 1);
  16.226 -(*YM3*)
  16.227 -by (Blast_tac 1);
  16.228 -qed "B_trusts_YM4_shrK";
  16.229 -
  16.230 -(** Up to now, the reasoning is similar to standard Yahalom.  Now the
  16.231 -    doubtful reasoning occurs.  We should not be assuming that an unknown
  16.232 -    key is secure, but the model allows us to: there is no Oops rule to
  16.233 -    let session keys go.*)
  16.234 -
  16.235 -(*B knows, by the second part of A's message, that the Server distributed 
  16.236 -  the key quoting nonce NB.  This part says nothing about agent names. 
  16.237 -  Secrecy of K is assumed; the valid Yahalom proof uses (and later proves)
  16.238 -  the secrecy of NB.*)
  16.239 -Goal "evs \\<in> yahalom                                          \
  16.240 -\     ==> Key K \\<notin> analz (knows Spy evs) -->                 \
  16.241 -\         Crypt K (Nonce NB) \\<in> parts (knows Spy evs) -->     \
  16.242 -\         (\\<exists>A B NA. Says Server A                          \
  16.243 -\                     {|Crypt (shrK A) {|Agent B, Key K,     \
  16.244 -\                               Nonce NA, Nonce NB|},        \
  16.245 -\                       Crypt (shrK B) {|Agent A, Key K|}|}  \
  16.246 -\                    \\<in> set evs)";
  16.247 -by (parts_induct_tac 1);
  16.248 -by (ALLGOALS Clarify_tac);
  16.249 -(*YM3 & Fake*)
  16.250 -by (Blast_tac 2);
  16.251 -by (Fake_parts_insert_tac 1);
  16.252 -(*YM4*)
  16.253 -(*A is uncompromised because NB is secure;
  16.254 -  A's certificate guarantees the existence of the Server message*)
  16.255 -by (blast_tac (claset() addSDs [Gets_imp_Says, Crypt_Spy_analz_bad]
  16.256 -			addDs  [Says_imp_spies, analz.Inj, 
  16.257 -			        parts.Inj RS parts.Fst RS A_trusts_YM3]) 1);
  16.258 -bind_thm ("B_trusts_YM4_newK", result() RS mp RSN (2, rev_mp));
  16.259 -
  16.260 -
  16.261 -(*B's session key guarantee from YM4.  The two certificates contribute to a
  16.262 -  single conclusion about the Server's message. *)
  16.263 -Goal "[| Gets B {|Crypt (shrK B) {|Agent A, Key K|},                    \
  16.264 -\                 Crypt K (Nonce NB)|} \\<in> set evs;                       \
  16.265 -\        Says B Server                                                  \
  16.266 -\          {|Agent B, Nonce NB, Crypt (shrK B) {|Agent A, Nonce NA|}|}  \
  16.267 -\          \\<in> set evs;                                                   \
  16.268 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]                         \
  16.269 -\      ==> \\<exists>na nb. Says Server A                                      \
  16.270 -\                  {|Crypt (shrK A) {|Agent B, Key K, na, nb|},         \
  16.271 -\                    Crypt (shrK B) {|Agent A, Key K|}|}                \
  16.272 -\            \\<in> set evs";
  16.273 -by (blast_tac (claset() addDs [B_trusts_YM4_newK, B_trusts_YM4_shrK, 
  16.274 -                          Spy_not_see_encrypted_key, unique_session_keys]) 1);
  16.275 -qed "B_trusts_YM4";
  16.276 -
  16.277 -
  16.278 -(*The obvious combination of B_trusts_YM4 with Spy_not_see_encrypted_key*)
  16.279 -Goal "[| Gets B {|Crypt (shrK B) {|Agent A, Key K|},                   \
  16.280 -\                    Crypt K (Nonce NB)|} \\<in> set evs;                   \
  16.281 -\        Says B Server                                                 \
  16.282 -\          {|Agent B, Nonce NB, Crypt (shrK B) {|Agent A, Nonce NA|}|} \
  16.283 -\          \\<in> set evs;                                                  \
  16.284 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]                \
  16.285 -\     ==> Key K \\<notin> analz (knows Spy evs)";
  16.286 -by (blast_tac (claset() addSDs [B_trusts_YM4, Spy_not_see_encrypted_key]) 1);
  16.287 -qed "B_gets_good_key";
  16.288 -
  16.289 -
  16.290 -(*** Authenticating B to A: these proofs are not considered.
  16.291 -     They are irrelevant to showing the need for Oops. ***)
  16.292 -
  16.293 -
  16.294 -(*** Authenticating A to B using the certificate Crypt K (Nonce NB) ***)
  16.295 -
  16.296 -(*Assuming the session key is secure, if both certificates are present then
  16.297 -  A has said NB.  We can't be sure about the rest of A's message, but only
  16.298 -  NB matters for freshness.*)  
  16.299 -Goal "evs \\<in> yahalom                                              \
  16.300 -\     ==> Key K \\<notin> analz (knows Spy evs) -->                     \
  16.301 -\         Crypt K (Nonce NB) \\<in> parts (knows Spy evs) -->         \
  16.302 -\         Crypt (shrK B) {|Agent A, Key K|} \\<in> parts (knows Spy evs) --> \
  16.303 -\         B \\<notin> bad -->                                           \
  16.304 -\         (\\<exists>X. Says A B {|X, Crypt K (Nonce NB)|} \\<in> set evs)";
  16.305 -by (parts_induct_tac 1);
  16.306 -(*Fake*)
  16.307 -by (Fake_parts_insert_tac 1);
  16.308 -(*YM3: by new_keys_not_used we note that Crypt K (Nonce NB) could not exist*)
  16.309 -by (force_tac (claset() addSDs [Crypt_imp_keysFor], simpset()) 1); 
  16.310 -(*YM4: was Crypt K (Nonce NB) the very last message?  If not, use ind. hyp.*)
  16.311 -by (asm_simp_tac (simpset() addsimps [ex_disj_distrib]) 1);
  16.312 -(*yes: apply unicity of session keys*)
  16.313 -by (blast_tac (claset() addSDs [Gets_imp_Says, A_trusts_YM3, B_trusts_YM4_shrK,
  16.314 -                                Crypt_Spy_analz_bad]
  16.315 -		addDs  [Says_imp_knows_Spy RS parts.Inj, 
  16.316 -                        Says_imp_spies RS analz.Inj, unique_session_keys]) 1);
  16.317 -qed_spec_mp "A_Said_YM3_lemma";
  16.318 -
  16.319 -(*If B receives YM4 then A has used nonce NB (and therefore is alive).
  16.320 -  Moreover, A associates K with NB (thus is talking about the same run).
  16.321 -  Other premises guarantee secrecy of K.*)
  16.322 -Goal "[| Gets B {|Crypt (shrK B) {|Agent A, Key K|},                   \
  16.323 -\                 Crypt K (Nonce NB)|} \\<in> set evs;                      \
  16.324 -\        Says B Server                                                 \
  16.325 -\          {|Agent B, Nonce NB, Crypt (shrK B) {|Agent A, Nonce NA|}|} \
  16.326 -\          \\<in> set evs;                                                  \
  16.327 -\        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> yahalom |]       \
  16.328 -\     ==> \\<exists>X. Says A B {|X, Crypt K (Nonce NB)|} \\<in> set evs";
  16.329 -by (blast_tac (claset() addSIs [A_Said_YM3_lemma]
  16.330 -                   addDs [Spy_not_see_encrypted_key, B_trusts_YM4,
  16.331 -                          Gets_imp_Says, Says_imp_knows_Spy RS parts.Inj]) 1);
  16.332 -qed_spec_mp "YM4_imp_A_Said_YM3";
    17.1 --- a/src/HOL/Auth/Yahalom_Bad.thy	Wed Apr 11 11:53:54 2001 +0200
    17.2 +++ b/src/HOL/Auth/Yahalom_Bad.thy	Thu Apr 12 12:45:05 2001 +0200
    17.3 @@ -5,62 +5,354 @@
    17.4  
    17.5  Inductive relation "yahalom" for the Yahalom protocol.
    17.6  
    17.7 -Example of why Oops is necessary.  This protocol can be attacked because it
    17.8 -doesn't keep NB secret, but without Oops it can be "verified" anyway.
    17.9 +Demonstrates of why Oops is necessary.  This protocol can be attacked because
   17.10 +it doesn't keep NB secret, but without Oops it can be "verified" anyway.
   17.11 +The issues are discussed in lcp's LICS 2000 invited lecture.
   17.12  *)
   17.13  
   17.14 -Yahalom_Bad = Shared + 
   17.15 +theory Yahalom_Bad = Shared:
   17.16  
   17.17 -consts  yahalom   :: event list set
   17.18 +consts  yahalom   :: "event list set"
   17.19  inductive "yahalom"
   17.20 -  intrs 
   17.21 +  intros
   17.22           (*Initial trace is empty*)
   17.23 -    Nil  "[] : yahalom"
   17.24 +   Nil:  "[] \<in> yahalom"
   17.25  
   17.26           (*The spy MAY say anything he CAN say.  We do not expect him to
   17.27             invent new nonces here, but he can also use NS1.  Common to
   17.28             all similar protocols.*)
   17.29 -    Fake "[| evsf \\<in> yahalom;  X \\<in> synth (analz (knows Spy evsf)) |]
   17.30 -          ==> Says Spy B X  # evsf \\<in> yahalom"
   17.31 +   Fake: "[| evsf \<in> yahalom;  X \<in> synth (analz (knows Spy evsf)) |]
   17.32 +          ==> Says Spy B X  # evsf \<in> yahalom"
   17.33  
   17.34           (*A message that has been sent can be received by the
   17.35             intended recipient.*)
   17.36 -    Reception "[| evsr \\<in> yahalom;  Says A B X \\<in> set evsr |]
   17.37 -               ==> Gets B X # evsr \\<in> yahalom"
   17.38 +   Reception: "[| evsr \<in> yahalom;  Says A B X \<in> set evsr |]
   17.39 +               ==> Gets B X # evsr \<in> yahalom"
   17.40  
   17.41           (*Alice initiates a protocol run*)
   17.42 -    YM1  "[| evs1 \\<in> yahalom;  Nonce NA \\<notin> used evs1 |]
   17.43 -          ==> Says A B {|Agent A, Nonce NA|} # evs1 \\<in> yahalom"
   17.44 +   YM1:  "[| evs1 \<in> yahalom;  Nonce NA \<notin> used evs1 |]
   17.45 +          ==> Says A B {|Agent A, Nonce NA|} # evs1 \<in> yahalom"
   17.46  
   17.47           (*Bob's response to Alice's message.*)
   17.48 -    YM2  "[| evs2 \\<in> yahalom;  Nonce NB \\<notin> used evs2;
   17.49 -             Gets B {|Agent A, Nonce NA|} \\<in> set evs2 |]
   17.50 -          ==> Says B Server 
   17.51 +   YM2:  "[| evs2 \<in> yahalom;  Nonce NB \<notin> used evs2;
   17.52 +             Gets B {|Agent A, Nonce NA|} \<in> set evs2 |]
   17.53 +          ==> Says B Server
   17.54                    {|Agent B, Nonce NB, Crypt (shrK B) {|Agent A, Nonce NA|}|}
   17.55 -                # evs2 \\<in> yahalom"
   17.56 +                # evs2 \<in> yahalom"
   17.57  
   17.58           (*The Server receives Bob's message.  He responds by sending a
   17.59              new session key to Alice, with a packet for forwarding to Bob.*)
   17.60 -    YM3  "[| evs3 \\<in> yahalom;  Key KAB \\<notin> used evs3;
   17.61 -             Gets Server 
   17.62 +   YM3:  "[| evs3 \<in> yahalom;  Key KAB \<notin> used evs3;
   17.63 +             Gets Server
   17.64                    {|Agent B, Nonce NB, Crypt (shrK B) {|Agent A, Nonce NA|}|}
   17.65 -               \\<in> set evs3 |]
   17.66 +               \<in> set evs3 |]
   17.67            ==> Says Server A
   17.68                     {|Crypt (shrK A) {|Agent B, Key KAB, Nonce NA, Nonce NB|},
   17.69                       Crypt (shrK B) {|Agent A, Key KAB|}|}
   17.70 -                # evs3 \\<in> yahalom"
   17.71 +                # evs3 \<in> yahalom"
   17.72  
   17.73           (*Alice receives the Server's (?) message, checks her Nonce, and
   17.74             uses the new session key to send Bob his Nonce.  The premise
   17.75 -           A \\<noteq> Server is needed to prove Says_Server_not_range.*)
   17.76 -    YM4  "[| evs4 \\<in> yahalom;  A \\<noteq> Server;
   17.77 +           A \<noteq> Server is needed to prove Says_Server_not_range.*)
   17.78 +   YM4:  "[| evs4 \<in> yahalom;  A \<noteq> Server;
   17.79               Gets A {|Crypt(shrK A) {|Agent B, Key K, Nonce NA, Nonce NB|}, X|}
   17.80 -                \\<in> set evs4;
   17.81 -             Says A B {|Agent A, Nonce NA|} \\<in> set evs4 |]
   17.82 -          ==> Says A B {|X, Crypt K (Nonce NB)|} # evs4 \\<in> yahalom"
   17.83 +                \<in> set evs4;
   17.84 +             Says A B {|Agent A, Nonce NA|} \<in> set evs4 |]
   17.85 +          ==> Says A B {|X, Crypt K (Nonce NB)|} # evs4 \<in> yahalom"
   17.86 +
   17.87 +
   17.88 +declare Says_imp_knows_Spy [THEN analz.Inj, dest]
   17.89 +declare parts.Body  [dest]
   17.90 +declare Fake_parts_insert_in_Un  [dest]
   17.91 +declare analz_into_parts [dest]
   17.92 +
   17.93 +
   17.94 +(*A "possibility property": there are traces that reach the end*)
   17.95 +lemma "A \<noteq> Server
   17.96 +      ==> \<exists>X NB K. \<exists>evs \<in> yahalom.
   17.97 +             Says A B {|X, Crypt K (Nonce NB)|} \<in> set evs"
   17.98 +apply (intro exI bexI)
   17.99 +apply (rule_tac [2] yahalom.Nil
  17.100 +                    [THEN yahalom.YM1, THEN yahalom.Reception,
  17.101 +                     THEN yahalom.YM2, THEN yahalom.Reception,
  17.102 +                     THEN yahalom.YM3, THEN yahalom.Reception,
  17.103 +                     THEN yahalom.YM4])
  17.104 +apply possibility
  17.105 +done
  17.106 +
  17.107 +lemma Gets_imp_Says:
  17.108 +     "[| Gets B X \<in> set evs; evs \<in> yahalom |] ==> \<exists>A. Says A B X \<in> set evs"
  17.109 +by (erule rev_mp, erule yahalom.induct, auto)
  17.110 +
  17.111 +(*Must be proved separately for each protocol*)
  17.112 +lemma Gets_imp_knows_Spy:
  17.113 +     "[| Gets B X \<in> set evs; evs \<in> yahalom |]  ==> X \<in> knows Spy evs"
  17.114 +by (blast dest!: Gets_imp_Says Says_imp_knows_Spy)
  17.115 +
  17.116 +declare Gets_imp_knows_Spy [THEN analz.Inj, dest]
  17.117 +
  17.118 +
  17.119 +(**** Inductive proofs about yahalom ****)
  17.120 +
  17.121 +(** For reasoning about the encrypted portion of messages **)
  17.122 +
  17.123 +(*Lets us treat YM4 using a similar argument as for the Fake case.*)
  17.124 +lemma YM4_analz_knows_Spy:
  17.125 +     "[| Gets A {|Crypt (shrK A) Y, X|} \<in> set evs;  evs \<in> yahalom |]
  17.126 +      ==> X \<in> analz (knows Spy evs)"
  17.127 +by blast
  17.128 +
  17.129 +lemmas YM4_parts_knows_Spy =
  17.130 +       YM4_analz_knows_Spy [THEN analz_into_parts, standard]
  17.131 +
  17.132 +
  17.133 +(** Theorems of the form X \<notin> parts (knows Spy evs) imply that NOBODY
  17.134 +    sends messages containing X! **)
  17.135 +
  17.136 +(*Spy never sees a good agent's shared key!*)
  17.137 +lemma Spy_see_shrK [simp]:
  17.138 +     "evs \<in> yahalom ==> (Key (shrK A) \<in> parts (knows Spy evs)) = (A \<in> bad)"
  17.139 +apply (erule yahalom.induct, force,
  17.140 +       drule_tac [6] YM4_parts_knows_Spy, simp_all)
  17.141 +apply blast+
  17.142 +done
  17.143 +
  17.144 +lemma Spy_analz_shrK [simp]:
  17.145 +     "evs \<in> yahalom ==> (Key (shrK A) \<in> analz (knows Spy evs)) = (A \<in> bad)"
  17.146 +by auto
  17.147 +
  17.148 +lemma Spy_see_shrK_D [dest!]:
  17.149 +     "[|Key (shrK A) \<in> parts (knows Spy evs);  evs \<in> yahalom|] ==> A \<in> bad"
  17.150 +by (blast dest: Spy_see_shrK)
  17.151 +
  17.152 +(*Nobody can have used non-existent keys!  Needed to apply analz_insert_Key*)
  17.153 +lemma new_keys_not_used [rule_format, simp]:
  17.154 + "evs \<in> yahalom ==> Key K \<notin> used evs --> K \<notin> keysFor (parts (knows Spy evs))"
  17.155 +apply (erule yahalom.induct, force,
  17.156 +       frule_tac [6] YM4_parts_knows_Spy, simp_all)
  17.157 +(*Fake, YM3, YM4*)
  17.158 +apply (blast dest!: keysFor_parts_insert)+
  17.159 +done
  17.160 +
  17.161 +
  17.162 +(****
  17.163 + The following is to prove theorems of the form
  17.164 +
  17.165 +  Key K \<in> analz (insert (Key KAB) (knows Spy evs)) ==>
  17.166 +  Key K \<in> analz (knows Spy evs)
  17.167 +
  17.168 + A more general formula must be proved inductively.
  17.169 +****)
  17.170 +
  17.171 +(** Session keys are not used to encrypt other session keys **)
  17.172 +
  17.173 +lemma analz_image_freshK [rule_format]:
  17.174 + "evs \<in> yahalom ==>
  17.175 +   \<forall>K KK. KK <= - (range shrK) -->
  17.176 +          (Key K \<in> analz (Key`KK Un (knows Spy evs))) =
  17.177 +          (K \<in> KK | Key K \<in> analz (knows Spy evs))"
  17.178 +apply (erule yahalom.induct, force,
  17.179 +       drule_tac [6] YM4_analz_knows_Spy)
  17.180 +apply analz_freshK
  17.181 +apply spy_analz
  17.182 +done
  17.183 +
  17.184 +lemma analz_insert_freshK: "[| evs \<in> yahalom;  KAB \<notin> range shrK |] ==>
  17.185 +      Key K \<in> analz (insert (Key KAB) (knows Spy evs)) =
  17.186 +      (K = KAB | Key K \<in> analz (knows Spy evs))"
  17.187 +by (simp only: analz_image_freshK analz_image_freshK_simps)
  17.188 +
  17.189 +
  17.190 +(*** The Key K uniquely identifies the Server's  message. **)
  17.191 +
  17.192 +lemma unique_session_keys:
  17.193 +     "[| Says Server A
  17.194 +          {|Crypt (shrK A) {|Agent B, Key K, na, nb|}, X|} \<in> set evs;
  17.195 +        Says Server A'
  17.196 +          {|Crypt (shrK A') {|Agent B', Key K, na', nb'|}, X'|} \<in> set evs;
  17.197 +        evs \<in> yahalom |]
  17.198 +     ==> A=A' & B=B' & na=na' & nb=nb'"
  17.199 +apply (erule rev_mp, erule rev_mp)
  17.200 +apply (erule yahalom.induct, simp_all)
  17.201 +(*YM3, by freshness, and YM4*)
  17.202 +apply blast+
  17.203 +done
  17.204 +
  17.205 +
  17.206 +(** Crucial secrecy property: Spy does not see the keys sent in msg YM3 **)
  17.207 +
  17.208 +lemma secrecy_lemma:
  17.209 +     "[| A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]
  17.210 +      ==> Says Server A
  17.211 +            {|Crypt (shrK A) {|Agent B, Key K, na, nb|},
  17.212 +              Crypt (shrK B) {|Agent A, Key K|}|}
  17.213 +           \<in> set evs -->
  17.214 +          Key K \<notin> analz (knows Spy evs)"
  17.215 +apply (erule yahalom.induct, force, drule_tac [6] YM4_analz_knows_Spy)
  17.216 +apply (simp_all add: pushes analz_insert_eq analz_insert_freshK)
  17.217 +apply spy_analz  (*Fake*)
  17.218 +apply (blast dest: unique_session_keys)  (*YM3*)
  17.219 +done
  17.220 +
  17.221 +(*Final version*)
  17.222 +lemma Spy_not_see_encrypted_key:
  17.223 +     "[| Says Server A
  17.224 +            {|Crypt (shrK A) {|Agent B, Key K, na, nb|},
  17.225 +              Crypt (shrK B) {|Agent A, Key K|}|}
  17.226 +           \<in> set evs;
  17.227 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]
  17.228 +      ==> Key K \<notin> analz (knows Spy evs)"
  17.229 +by (blast dest: secrecy_lemma)
  17.230 +
  17.231  
  17.232 -         (*This message models possible leaks of session keys.  The Nonces
  17.233 -           identify the protocol run.  Quoting Server here ensures they are
  17.234 -           correct.*)
  17.235 +(** Security Guarantee for A upon receiving YM3 **)
  17.236 +
  17.237 +(*If the encrypted message appears then it originated with the Server*)
  17.238 +lemma A_trusts_YM3:
  17.239 +     "[| Crypt (shrK A) {|Agent B, Key K, na, nb|} \<in> parts (knows Spy evs);
  17.240 +         A \<notin> bad;  evs \<in> yahalom |]
  17.241 +       ==> Says Server A
  17.242 +            {|Crypt (shrK A) {|Agent B, Key K, na, nb|},
  17.243 +              Crypt (shrK B) {|Agent A, Key K|}|}
  17.244 +           \<in> set evs"
  17.245 +apply (erule rev_mp)
  17.246 +apply (erule yahalom.induct, force,
  17.247 +       frule_tac [6] YM4_parts_knows_Spy, simp_all)
  17.248 +(*Fake, YM3*)
  17.249 +apply blast+
  17.250 +done
  17.251 +
  17.252 +(*The obvious combination of A_trusts_YM3 with Spy_not_see_encrypted_key*)
  17.253 +lemma A_gets_good_key:
  17.254 +     "[| Crypt (shrK A) {|Agent B, Key K, na, nb|} \<in> parts (knows Spy evs);
  17.255 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]
  17.256 +      ==> Key K \<notin> analz (knows Spy evs)"
  17.257 +by (blast dest!: A_trusts_YM3 Spy_not_see_encrypted_key)
  17.258 +
  17.259 +(** Security Guarantees for B upon receiving YM4 **)
  17.260 +
  17.261 +(*B knows, by the first part of A's message, that the Server distributed
  17.262 +  the key for A and B.  But this part says nothing about nonces.*)
  17.263 +lemma B_trusts_YM4_shrK:
  17.264 +     "[| Crypt (shrK B) {|Agent A, Key K|} \<in> parts (knows Spy evs);
  17.265 +         B \<notin> bad;  evs \<in> yahalom |]
  17.266 +      ==> \<exists>NA NB. Says Server A
  17.267 +                      {|Crypt (shrK A) {|Agent B, Key K, Nonce NA, Nonce NB|},
  17.268 +                        Crypt (shrK B) {|Agent A, Key K|}|}
  17.269 +                     \<in> set evs"
  17.270 +apply (erule rev_mp)
  17.271 +apply (erule yahalom.induct, force,
  17.272 +       frule_tac [6] YM4_parts_knows_Spy, simp_all)
  17.273 +(*Fake, YM3*)
  17.274 +apply blast+
  17.275 +done
  17.276 +
  17.277 +(** Up to now, the reasoning is similar to standard Yahalom.  Now the
  17.278 +    doubtful reasoning occurs.  We should not be assuming that an unknown
  17.279 +    key is secure, but the model allows us to: there is no Oops rule to
  17.280 +    let session keys become compromised.*)
  17.281 +
  17.282 +(*B knows, by the second part of A's message, that the Server distributed
  17.283 +  the key quoting nonce NB.  This part says nothing about agent names.
  17.284 +  Secrecy of K is assumed; the valid Yahalom proof uses (and later proves)
  17.285 +  the secrecy of NB.*)
  17.286 +lemma B_trusts_YM4_newK [rule_format]:
  17.287 +     "[|Key K \<notin> analz (knows Spy evs);  evs \<in> yahalom|]
  17.288 +      ==> Crypt K (Nonce NB) \<in> parts (knows Spy evs) -->
  17.289 +          (\<exists>A B NA. Says Server A
  17.290 +                      {|Crypt (shrK A) {|Agent B, Key K,
  17.291 +                                Nonce NA, Nonce NB|},
  17.292 +                        Crypt (shrK B) {|Agent A, Key K|}|}
  17.293 +                     \<in> set evs)"
  17.294 +apply (erule rev_mp)
  17.295 +apply (erule yahalom.induct, force,
  17.296 +       frule_tac [6] YM4_parts_knows_Spy)
  17.297 +apply (analz_mono_contra, simp_all)
  17.298 +(*Fake*)
  17.299 +apply blast
  17.300 +(*YM3*)
  17.301 +apply blast
  17.302 +(*A is uncompromised because NB is secure
  17.303 +  A's certificate guarantees the existence of the Server message*)
  17.304 +apply (blast dest!: Gets_imp_Says Crypt_Spy_analz_bad
  17.305 +             dest: Says_imp_spies
  17.306 +                   parts.Inj [THEN parts.Fst, THEN A_trusts_YM3])
  17.307 +done
  17.308 +
  17.309 +
  17.310 +(*B's session key guarantee from YM4.  The two certificates contribute to a
  17.311 +  single conclusion about the Server's message. *)
  17.312 +lemma B_trusts_YM4:
  17.313 +     "[| Gets B {|Crypt (shrK B) {|Agent A, Key K|},
  17.314 +                  Crypt K (Nonce NB)|} \<in> set evs;
  17.315 +         Says B Server
  17.316 +           {|Agent B, Nonce NB, Crypt (shrK B) {|Agent A, Nonce NA|}|}
  17.317 +           \<in> set evs;
  17.318 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]
  17.319 +       ==> \<exists>na nb. Says Server A
  17.320 +                   {|Crypt (shrK A) {|Agent B, Key K, na, nb|},
  17.321 +                     Crypt (shrK B) {|Agent A, Key K|}|}
  17.322 +             \<in> set evs"
  17.323 +by (blast dest: B_trusts_YM4_newK B_trusts_YM4_shrK Spy_not_see_encrypted_key
  17.324 +                unique_session_keys)
  17.325 +
  17.326 +
  17.327 +(*The obvious combination of B_trusts_YM4 with Spy_not_see_encrypted_key*)
  17.328 +lemma B_gets_good_key:
  17.329 +     "[| Gets B {|Crypt (shrK B) {|Agent A, Key K|},
  17.330 +                  Crypt K (Nonce NB)|} \<in> set evs;
  17.331 +         Says B Server
  17.332 +           {|Agent B, Nonce NB, Crypt (shrK B) {|Agent A, Nonce NA|}|}
  17.333 +           \<in> set evs;
  17.334 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]
  17.335 +      ==> Key K \<notin> analz (knows Spy evs)"
  17.336 +by (blast dest!: B_trusts_YM4 Spy_not_see_encrypted_key)
  17.337 +
  17.338 +
  17.339 +(*** Authenticating B to A: these proofs are not considered.
  17.340 +     They are irrelevant to showing the need for Oops. ***)
  17.341 +
  17.342 +
  17.343 +(*** Authenticating A to B using the certificate Crypt K (Nonce NB) ***)
  17.344 +
  17.345 +(*Assuming the session key is secure, if both certificates are present then
  17.346 +  A has said NB.  We can't be sure about the rest of A's message, but only
  17.347 +  NB matters for freshness.*)
  17.348 +lemma A_Said_YM3_lemma [rule_format]:
  17.349 +     "evs \<in> yahalom
  17.350 +      ==> Key K \<notin> analz (knows Spy evs) -->
  17.351 +          Crypt K (Nonce NB) \<in> parts (knows Spy evs) -->
  17.352 +          Crypt (shrK B) {|Agent A, Key K|} \<in> parts (knows Spy evs) -->
  17.353 +          B \<notin> bad -->
  17.354 +          (\<exists>X. Says A B {|X, Crypt K (Nonce NB)|} \<in> set evs)"
  17.355 +apply (erule yahalom.induct, force,
  17.356 +       frule_tac [6] YM4_parts_knows_Spy)
  17.357 +apply (analz_mono_contra, simp_all)
  17.358 +(*Fake*)
  17.359 +apply blast
  17.360 +(*YM3: by new_keys_not_used we note that Crypt K (Nonce NB) could not exist*)
  17.361 +apply (force dest!: Crypt_imp_keysFor)
  17.362 +(*YM4: was Crypt K (Nonce NB) the very last message?  If not, use ind. hyp.*)
  17.363 +apply (simp add: ex_disj_distrib)
  17.364 +(*yes: apply unicity of session keys*)
  17.365 +apply (blast dest!: Gets_imp_Says A_trusts_YM3 B_trusts_YM4_shrK
  17.366 +                    Crypt_Spy_analz_bad
  17.367 +             dest: Says_imp_knows_Spy [THEN parts.Inj] unique_session_keys)
  17.368 +done
  17.369 +
  17.370 +(*If B receives YM4 then A has used nonce NB (and therefore is alive).
  17.371 +  Moreover, A associates K with NB (thus is talking about the same run).
  17.372 +  Other premises guarantee secrecy of K.*)
  17.373 +lemma YM4_imp_A_Said_YM3 [rule_format]:
  17.374 +     "[| Gets B {|Crypt (shrK B) {|Agent A, Key K|},
  17.375 +                  Crypt K (Nonce NB)|} \<in> set evs;
  17.376 +         Says B Server
  17.377 +           {|Agent B, Nonce NB, Crypt (shrK B) {|Agent A, Nonce NA|}|}
  17.378 +           \<in> set evs;
  17.379 +         A \<notin> bad;  B \<notin> bad;  evs \<in> yahalom |]
  17.380 +      ==> \<exists>X. Says A B {|X, Crypt K (Nonce NB)|} \<in> set evs"
  17.381 +apply (blast intro!: A_Said_YM3_lemma
  17.382 +            dest: Spy_not_see_encrypted_key B_trusts_YM4 Gets_imp_Says)
  17.383 +done
  17.384  
  17.385  end
    18.1 --- a/src/HOL/IsaMakefile	Wed Apr 11 11:53:54 2001 +0200
    18.2 +++ b/src/HOL/IsaMakefile	Thu Apr 12 12:45:05 2001 +0200
    18.3 @@ -304,15 +304,13 @@
    18.4  $(LOG)/HOL-Auth.gz: $(OUT)/HOL Auth/Event_lemmas.ML Auth/Event.thy \
    18.5    Auth/Message_lemmas.ML Auth/Message.thy Auth/NS_Public.thy \
    18.6    Auth/NS_Public_Bad.thy \
    18.7 -  Auth/NS_Shared.thy Auth/OtwayRees.ML Auth/OtwayRees.thy \
    18.8 -  Auth/OtwayRees_AN.ML Auth/OtwayRees_AN.thy Auth/OtwayRees_Bad.ML \
    18.9 +  Auth/NS_Shared.thy Auth/OtwayRees.thy Auth/OtwayRees_AN.thy \
   18.10    Auth/OtwayRees_Bad.thy Auth/Public_lemmas.ML Auth/Public.thy Auth/ROOT.ML \
   18.11    Auth/Recur.ML Auth/Recur.thy Auth/Shared_lemmas.ML Auth/Shared.thy \
   18.12 -  Auth/TLS.ML Auth/TLS.thy Auth/WooLam.ML Auth/WooLam.thy \
   18.13 +  Auth/TLS.ML Auth/TLS.thy Auth/WooLam.thy \
   18.14    Auth/Kerberos_BAN.ML Auth/Kerberos_BAN.thy \
   18.15    Auth/KerberosIV.ML Auth/KerberosIV.thy \
   18.16 -  Auth/Yahalom.ML Auth/Yahalom.thy Auth/Yahalom2.ML Auth/Yahalom2.thy \
   18.17 -  Auth/Yahalom_Bad.ML Auth/Yahalom_Bad.thy
   18.18 +  Auth/Yahalom.thy Auth/Yahalom2.thy Auth/Yahalom_Bad.thy
   18.19  	@$(ISATOOL) usedir $(OUT)/HOL Auth
   18.20  
   18.21