src/HOL/Auth/NS_Shared.thy
changeset 18886 9f27383426db
parent 17778 93d7e524417a
child 23746 a455e69c31cc
equal deleted inserted replaced
18885:ee8b5c36ba2b 18886:9f27383426db
     1 (*  Title:      HOL/Auth/NS_Shared
     1 (*  Title:      HOL/Auth/NS_Shared
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     3     Author:     Lawrence C Paulson and Giampaolo Bella 
     4     Copyright   1996  University of Cambridge
     4     Copyright   1996  University of Cambridge
     5 *)
     5 *)
     6 
     6 
     7 header{*The Needham-Schroeder Shared-Key Protocol*}
     7 header{*Needham-Schroeder Shared-Key Protocol and the Issues Property*}
     8 
     8 
     9 theory NS_Shared imports Public begin
     9 theory NS_Shared imports Public begin
    10 
    10 
    11 text{*
    11 text{*
    12 From page 247 of
    12 From page 247 of
    13   Burrows, Abadi and Needham (1989).  A Logic of Authentication.
    13   Burrows, Abadi and Needham (1989).  A Logic of Authentication.
    14   Proc. Royal Soc. 426
    14   Proc. Royal Soc. 426
    15 *}
    15 *}
       
    16 
       
    17 constdefs
       
    18 
       
    19  (* A is the true creator of X if she has sent X and X never appeared on
       
    20     the trace before this event. Recall that traces grow from head. *)
       
    21   Issues :: "[agent, agent, msg, event list] => bool"
       
    22              ("_ Issues _ with _ on _")
       
    23    "A Issues B with X on evs ==
       
    24       \<exists>Y. Says A B Y \<in> set evs & X \<in> parts {Y} &
       
    25       X \<notin> parts (spies (takeWhile (% z. z  \<noteq> Says A B Y) (rev evs)))"
       
    26 
    16 
    27 
    17 consts  ns_shared   :: "event list set"
    28 consts  ns_shared   :: "event list set"
    18 inductive "ns_shared"
    29 inductive "ns_shared"
    19  intros
    30  intros
    20 	(*Initial trace is empty*)
    31 	(*Initial trace is empty*)
   240 text{*In messages of this form, the session key uniquely identifies the rest*}
   251 text{*In messages of this form, the session key uniquely identifies the rest*}
   241 lemma unique_session_keys:
   252 lemma unique_session_keys:
   242      "\<lbrakk>Says Server A (Crypt (shrK A) \<lbrace>NA, Agent B, Key K, X\<rbrace>) \<in> set evs;
   253      "\<lbrakk>Says Server A (Crypt (shrK A) \<lbrace>NA, Agent B, Key K, X\<rbrace>) \<in> set evs;
   243        Says Server A' (Crypt (shrK A') \<lbrace>NA', Agent B', Key K, X'\<rbrace>) \<in> set evs;
   254        Says Server A' (Crypt (shrK A') \<lbrace>NA', Agent B', Key K, X'\<rbrace>) \<in> set evs;
   244        evs \<in> ns_shared\<rbrakk> \<Longrightarrow> A=A' \<and> NA=NA' \<and> B=B' \<and> X = X'"
   255        evs \<in> ns_shared\<rbrakk> \<Longrightarrow> A=A' \<and> NA=NA' \<and> B=B' \<and> X = X'"
   245 apply (erule rev_mp, erule rev_mp, erule ns_shared.induct, simp_all, blast+)
   256 by (erule rev_mp, erule rev_mp, erule ns_shared.induct, simp_all, blast+)
   246 done
   257 
   247 
   258 
   248 
   259 subsubsection{*Crucial secrecy property: Spy doesn't see the keys sent in NS2*}
   249 subsubsection{*Crucial secrecy property: Spy does not see the keys sent in msg NS2*}
       
   250 
   260 
   251 text{*Beware of @{text "[rule_format]"} and the universal quantifier!*}
   261 text{*Beware of @{text "[rule_format]"} and the universal quantifier!*}
   252 lemma secrecy_lemma:
   262 lemma secrecy_lemma:
   253      "\<lbrakk>Says Server A (Crypt (shrK A) \<lbrace>NA, Agent B, Key K,
   263      "\<lbrakk>Says Server A (Crypt (shrK A) \<lbrace>NA, Agent B, Key K,
   254                                       Crypt (shrK B) \<lbrace>Key K, Agent A\<rbrace>\<rbrace>)
   264                                       Crypt (shrK B) \<lbrace>Key K, Agent A\<rbrace>\<rbrace>)
   331   "evs \<in> ns_shared \<Longrightarrow>
   341   "evs \<in> ns_shared \<Longrightarrow>
   332      Key K \<notin> analz (spies evs) \<longrightarrow>
   342      Key K \<notin> analz (spies evs) \<longrightarrow>
   333      Says Server A (Crypt (shrK A) \<lbrace>NA, Agent B, Key K, X\<rbrace>) \<in> set evs \<longrightarrow>
   343      Says Server A (Crypt (shrK A) \<lbrace>NA, Agent B, Key K, X\<rbrace>) \<in> set evs \<longrightarrow>
   334      Crypt K (Nonce NB) \<in> parts (spies evs) \<longrightarrow>
   344      Crypt K (Nonce NB) \<in> parts (spies evs) \<longrightarrow>
   335      (\<exists>A'. Says A' B X \<in> set evs)"
   345      (\<exists>A'. Says A' B X \<in> set evs)"
   336 apply (erule ns_shared.induct, force, drule_tac [4] NS3_msg_in_parts_spies, analz_mono_contra)
   346 apply (erule ns_shared.induct, force)
       
   347 apply (drule_tac [4] NS3_msg_in_parts_spies)
       
   348 apply analz_mono_contra
   337 apply (simp_all add: ex_disj_distrib, blast)
   349 apply (simp_all add: ex_disj_distrib, blast)
   338 txt{*NS2*}
   350 txt{*NS2*}
   339 apply (blast dest!: new_keys_not_used Crypt_imp_keysFor)
   351 apply (blast dest!: new_keys_not_used Crypt_imp_keysFor)
   340 txt{*NS4*}
   352 txt{*NS4*}
   341 apply (blast dest: B_trusts_NS3
   353 apply (blast dest: B_trusts_NS3
   350      Says Server A
   362      Says Server A
   351 	  (Crypt (shrK A) \<lbrace>NA, Agent B, Key K,
   363 	  (Crypt (shrK A) \<lbrace>NA, Agent B, Key K,
   352 			    Crypt (shrK B) \<lbrace>Key K, Agent A\<rbrace>\<rbrace>) \<in> set evs \<longrightarrow>
   364 			    Crypt (shrK B) \<lbrace>Key K, Agent A\<rbrace>\<rbrace>) \<in> set evs \<longrightarrow>
   353      Crypt K \<lbrace>Nonce NB, Nonce NB\<rbrace> \<in> parts (spies evs) \<longrightarrow>
   365      Crypt K \<lbrace>Nonce NB, Nonce NB\<rbrace> \<in> parts (spies evs) \<longrightarrow>
   354      Says A B (Crypt K \<lbrace>Nonce NB, Nonce NB\<rbrace>) \<in> set evs"
   366      Says A B (Crypt K \<lbrace>Nonce NB, Nonce NB\<rbrace>) \<in> set evs"
   355 apply (erule ns_shared.induct, force, drule_tac [4] NS3_msg_in_parts_spies, analz_mono_contra, simp_all, blast)
   367 apply (erule ns_shared.induct, force)
       
   368 apply (drule_tac [4] NS3_msg_in_parts_spies)
       
   369 apply (analz_mono_contra, simp_all, blast)
   356 txt{*NS2*}
   370 txt{*NS2*}
   357 apply (blast dest!: new_keys_not_used Crypt_imp_keysFor)
   371 apply (blast dest!: new_keys_not_used Crypt_imp_keysFor)
   358 txt{*NS5*}
   372 txt{*NS5*}
   359 apply (blast dest!: A_trusts_NS2
   373 apply (blast dest!: A_trusts_NS2
   360 	     dest: Says_imp_knows_Spy [THEN analz.Inj]
   374 	     dest: Says_imp_knows_Spy [THEN analz.Inj]
   370        A \<notin> bad;  B \<notin> bad;  evs \<in> ns_shared\<rbrakk>
   384        A \<notin> bad;  B \<notin> bad;  evs \<in> ns_shared\<rbrakk>
   371       \<Longrightarrow> Says A B (Crypt K \<lbrace>Nonce NB, Nonce NB\<rbrace>) \<in> set evs"
   385       \<Longrightarrow> Says A B (Crypt K \<lbrace>Nonce NB, Nonce NB\<rbrace>) \<in> set evs"
   372 by (blast intro: B_trusts_NS5_lemma
   386 by (blast intro: B_trusts_NS5_lemma
   373           dest: B_trusts_NS3 Spy_not_see_encrypted_key)
   387           dest: B_trusts_NS3 Spy_not_see_encrypted_key)
   374 
   388 
       
   389 text{*Unaltered so far wrt original version*}
       
   390 
       
   391 subsection{*Lemmas for reasoning about predicate "Issues"*}
       
   392 
       
   393 lemma spies_Says_rev: "spies (evs @ [Says A B X]) = insert X (spies evs)"
       
   394 apply (induct_tac "evs")
       
   395 apply (induct_tac [2] "a", auto)
       
   396 done
       
   397 
       
   398 lemma spies_Gets_rev: "spies (evs @ [Gets A X]) = spies evs"
       
   399 apply (induct_tac "evs")
       
   400 apply (induct_tac [2] "a", auto)
       
   401 done
       
   402 
       
   403 lemma spies_Notes_rev: "spies (evs @ [Notes A X]) =
       
   404           (if A:bad then insert X (spies evs) else spies evs)"
       
   405 apply (induct_tac "evs")
       
   406 apply (induct_tac [2] "a", auto)
       
   407 done
       
   408 
       
   409 lemma spies_evs_rev: "spies evs = spies (rev evs)"
       
   410 apply (induct_tac "evs")
       
   411 apply (induct_tac [2] "a")
       
   412 apply (simp_all (no_asm_simp) add: spies_Says_rev spies_Gets_rev spies_Notes_rev)
       
   413 done
       
   414 
       
   415 lemmas parts_spies_evs_revD2 = spies_evs_rev [THEN equalityD2, THEN parts_mono]
       
   416 
       
   417 lemma spies_takeWhile: "spies (takeWhile P evs) <=  spies evs"
       
   418 apply (induct_tac "evs")
       
   419 apply (induct_tac [2] "a", auto)
       
   420 txt{* Resembles @{text"used_subset_append"} in theory Event.*}
       
   421 done
       
   422 
       
   423 lemmas parts_spies_takeWhile_mono = spies_takeWhile [THEN parts_mono]
       
   424 
       
   425 
       
   426 subsection{*Guarantees of non-injective agreement on the session key, and
       
   427 of key distribution. They also express forms of freshness of certain messages,
       
   428 namely that agents were alive after something happened.*}
       
   429 
       
   430 lemma B_Issues_A:
       
   431      "\<lbrakk> Says B A (Crypt K (Nonce Nb)) \<in> set evs;
       
   432          Key K \<notin> analz (spies evs);
       
   433          A \<notin> bad;  B \<notin> bad; evs \<in> ns_shared \<rbrakk>
       
   434       \<Longrightarrow> B Issues A with (Crypt K (Nonce Nb)) on evs"
       
   435 apply (simp (no_asm) add: Issues_def)
       
   436 apply (rule exI)
       
   437 apply (rule conjI, assumption)
       
   438 apply (simp (no_asm))
       
   439 apply (erule rev_mp)
       
   440 apply (erule rev_mp)
       
   441 apply (erule ns_shared.induct, analz_mono_contra)
       
   442 apply (simp_all)
       
   443 txt{*fake*}
       
   444 apply blast
       
   445 apply (simp_all add: takeWhile_tail)
       
   446 txt{*NS3 remains by pure coincidence!*}
       
   447 apply (force dest!: A_trusts_NS2 Says_Server_message_form)
       
   448 txt{*NS4 would be the non-trivial case can be solved by Nb being used*}
       
   449 apply (blast dest: parts_spies_takeWhile_mono [THEN subsetD]
       
   450                    parts_spies_evs_revD2 [THEN subsetD])
       
   451 done
       
   452 
       
   453 text{*Tells A that B was alive after she sent him the session key.  The
       
   454 session key must be assumed confidential for this deduction to be meaningful,
       
   455 but that assumption can be relaxed by the appropriate argument.
       
   456 
       
   457 Precisely, the theorem guarantees (to A) key distribution of the session key
       
   458 to B. It also guarantees (to A) non-injective agreement of B with A on the
       
   459 session key. Both goals are available to A in the sense of Goal Availability.
       
   460 *}
       
   461 lemma A_authenticates_and_keydist_to_B:
       
   462      "\<lbrakk>Crypt K (Nonce NB) \<in> parts (spies evs);
       
   463        Crypt (shrK A) \<lbrace>NA, Agent B, Key K, X\<rbrace> \<in> parts (spies evs);
       
   464        Key K \<notin> analz(knows Spy evs);
       
   465        A \<notin> bad;  B \<notin> bad;  evs \<in> ns_shared\<rbrakk>
       
   466       \<Longrightarrow> B Issues A with (Crypt K (Nonce NB)) on evs"
       
   467 by (blast intro: A_trusts_NS4_lemma B_Issues_A dest: A_trusts_NS2)
       
   468 
       
   469 lemma A_trusts_NS5:
       
   470   "\<lbrakk> Crypt K \<lbrace>Nonce NB, Nonce NB\<rbrace> \<in> parts(spies evs);
       
   471      Crypt (shrK A) \<lbrace>Nonce NA, Agent B, Key K, X\<rbrace> \<in> parts(spies evs);
       
   472      Key K \<notin> analz (spies evs);
       
   473      A \<notin> bad; B \<notin> bad; evs \<in> ns_shared \<rbrakk>
       
   474  \<Longrightarrow> Says A B (Crypt K \<lbrace>Nonce NB, Nonce NB\<rbrace>) \<in> set evs";
       
   475 apply (erule rev_mp)
       
   476 apply (erule rev_mp)
       
   477 apply (erule rev_mp)
       
   478 apply (erule ns_shared.induct, analz_mono_contra)
       
   479 apply (frule_tac [5] Says_S_message_form)
       
   480 apply (simp_all)
       
   481 txt{*Fake*}
       
   482 apply blast
       
   483 txt{*NS2*}
       
   484 apply (force dest!: Crypt_imp_keysFor)
       
   485 txt{*NS3, much quicker having installed @{term Says_S_message_form} before simplication*}
       
   486 apply fastsimp
       
   487 txt{*NS5, the most important case, can be solved by unicity*}
       
   488 apply (case_tac "Aa \<in> bad")
       
   489 apply (force dest!: Says_imp_spies [THEN analz.Inj, THEN analz.Decrypt, THEN analz.Snd, THEN analz.Snd, THEN analz.Fst])
       
   490 apply (blast dest: A_trusts_NS2 unique_session_keys)
       
   491 done
       
   492 
       
   493 lemma A_Issues_B:
       
   494      "\<lbrakk> Says A B (Crypt K \<lbrace>Nonce NB, Nonce NB\<rbrace>) \<in> set evs;
       
   495         Key K \<notin> analz (spies evs);
       
   496         A \<notin> bad;  B \<notin> bad; evs \<in> ns_shared \<rbrakk>
       
   497     \<Longrightarrow> A Issues B with (Crypt K \<lbrace>Nonce NB, Nonce NB\<rbrace>) on evs"
       
   498 apply (simp (no_asm) add: Issues_def)
       
   499 apply (rule exI)
       
   500 apply (rule conjI, assumption)
       
   501 apply (simp (no_asm))
       
   502 apply (erule rev_mp)
       
   503 apply (erule rev_mp)
       
   504 apply (erule ns_shared.induct, analz_mono_contra)
       
   505 apply (simp_all)
       
   506 txt{*fake*}
       
   507 apply blast
       
   508 apply (simp_all add: takeWhile_tail)
       
   509 txt{*NS3 remains by pure coincidence!*}
       
   510 apply (force dest!: A_trusts_NS2 Says_Server_message_form)
       
   511 txt{*NS5 is the non-trivial case and cannot be solved as in @{term B_Issues_A}! because NB is not fresh. We need @{term A_trusts_NS5}, proved for this very purpose*}
       
   512 apply (blast dest: A_trusts_NS5 parts_spies_takeWhile_mono [THEN subsetD]
       
   513         parts_spies_evs_revD2 [THEN subsetD])
       
   514 done
       
   515 
       
   516 text{*Tells B that A was alive after B issued NB.
       
   517 
       
   518 Precisely, the theorem guarantees (to B) key distribution of the session key to A. It also guarantees (to B) non-injective agreement of A with B on the session key. Both goals are available to B in the sense of Goal Availability.
       
   519 *}
       
   520 lemma B_authenticates_and_keydist_to_A:
       
   521      "\<lbrakk>Crypt K \<lbrace>Nonce NB, Nonce NB\<rbrace> \<in> parts (spies evs);
       
   522        Crypt (shrK B) \<lbrace>Key K, Agent A\<rbrace> \<in> parts (spies evs);
       
   523        Key K \<notin> analz (spies evs);
       
   524        A \<notin> bad;  B \<notin> bad;  evs \<in> ns_shared\<rbrakk>
       
   525    \<Longrightarrow> A Issues B with (Crypt K \<lbrace>Nonce NB, Nonce NB\<rbrace>) on evs"
       
   526 by (blast intro: A_Issues_B B_trusts_NS5_lemma dest: B_trusts_NS3)
       
   527 
   375 end
   528 end