Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/HOL/UNITY/Simple/   (Beweissystem Isabelle Version 2025-1©)  Datei vom 16.11.2025 mit Größe 12 kB image not shown  

Quelle  NSP_Bad.thy   Sprache: Isabelle

 
(*  Title:      HOL/UNITY/Simple/NSP_Bad.thy
    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
    Copyright   1996  University of Cambridge

Original file is ../Auth/NS_Public_Bad
*)


sectionAnalyzing the Needham-Schroeder Public-Key Protocol in UNITY

theory NSP_Bad imports "HOL-Auth.Public" "../UNITY_Main" begin

textThis is the flawed version, vulnerable to Lowe's attack.
From page 260 of
  Burrows, Abadi and Needham.  A Logic of Authentication.
  Proc. Royal Soc. 426 (1989).


type_synonym state = "event list"

  (*The spy MAY say anything he CAN say.  We do not expect him to
    invent new nonces here, but he can also use NS1.  Common to
    all similar protocols.*)

definition
  Fake :: "(state*state) set"
  where "Fake = {(s,s').
              B X. s' = Says Spy B X # s
                    & X  synth (analz (spies s))}"

  (*The numeric suffixes on A identify the rule*)

  (*Alice initiates a protocol run, sending a nonce to Bob*)
definition
  NS1 :: "(state*state) set"
  where "NS1 = {(s1,s').
             A1 B NA.
                 s' = Says A1 B (Crypt (pubK B) \Nonce NA, Agent A1\) # s1
               & Nonce NA  used s1}"

  (*Bob responds to Alice's message with a further nonce*)
definition
  NS2 :: "(state*state) set"
  where "NS2 = {(s2,s').
             A' A2 B NA NB.
                 s' = Says B A2 (Crypt (pubK A2) \Nonce NA, Nonce NB\) # s2
               & Says A' B (Crypt (pubK B) \Nonce NA, Agent A2\) \ set s2
               & Nonce NB  used s2}"

  (*Alice proves her existence by sending NB back to Bob.*)
definition
  NS3 :: "(state*state) set"
  where "NS3 = {(s3,s').
             A3 B' B NA NB.
                 s' = Says A3 B (Crypt (pubK B) (Nonce NB)) # s3
               & Says A3  B (Crypt (pubK B) {Nonce NA, Agent A3} set s3
               & Says B' A3 (Crypt (pubK A3) \Nonce NA, Nonce NB\) \ set s3}"


definition Nprg :: "state program" where
    (*Initial trace is empty*)
    "Nprg = mk_total_program({[]}, {Fake, NS1, NS2, NS3}, UNIV)"

declare spies_partsEs [elim]
declare analz_into_parts [dest]
declare Fake_parts_insert_in_Un  [dest]

textFor other theories, e.g. Mutex and Lift, using [iff] slows proofs down.
  Here, it facilitates re-use of the Auth proofs.

declare Fake_def [THEN def_act_simp, iff]
declare NS1_def [THEN def_act_simp, iff]
declare NS2_def [THEN def_act_simp, iff]
declare NS3_def [THEN def_act_simp, iff]

declare Nprg_def [THEN def_prg_Init, simp]


text"possibility property": there are traces that reach the end.
  Replace by LEADSTO proof!
lemma "A \ B ==>
       NB.  reachable Nprg. Says A B (Crypt (pubK B) (Nonce NB))  set s"
apply (intro exI bexI)
apply (rule_tac [2] act = "totalize_act NS3" in reachable.Acts)
apply (rule_tac [3] act = "totalize_act NS2" in reachable.Acts)
apply (rule_tac [4] act = "totalize_act NS1" in reachable.Acts)
apply (rule_tac [5] reachable.Init)
apply (simp_all (no_asm_simp) add: Nprg_def totalize_act_def)
apply auto
done


subsectionInductive Proofs about 🍋ns_public

lemma ns_constrainsI:
     "(!!act s s'. [| act \ {Id, Fake, NS1, NS2, NS3};
                      (s,s') \ act; s \ A |] ==> s'  A')
      ==> Nprg  A co A'"
apply (simp add: Nprg_def mk_total_program_def)
apply (rule constrainsI, auto)
done


textThis ML code does the inductions directly.
ML
fun ns_constrains_tac ctxt i =
  SELECT_GOAL
    (EVERY
     [REPEAT (eresolve_tac ctxt @{thms Always_ConstrainsI} 1),
      REPEAT (resolve_tac ctxt [@{thm StableI}, @{thm stableI}, @{thm constrains_imp_Constrains}] 1),
      resolve_tac ctxt @{thms ns_constrainsI} 1,
      full_simp_tac ctxt 1,
      REPEAT (FIRSTGOAL (eresolve_tac ctxt [disjE])),
      ALLGOALS (clarify_tac (ctxt delrules [impI, @{thm impCE}])),
      REPEAT (FIRSTGOAL (analz_mono_contra_tac ctxt)),
      ALLGOALS (asm_simp_tac ctxt)]) i;

(*Tactic for proving secrecy theorems*)
fun ns_induct_tac ctxt =
  (SELECT_GOAL o EVERY)
     [resolve_tac ctxt @{thms AlwaysI} 1,
      force_tac ctxt 1,
      (*"reachable" gets in here*)
      resolve_tac ctxt [@{thm Always_reachable} RS @{thm Always_ConstrainsI} RS @{thm StableI}] 1,
      ns_constrains_tac ctxt 1];


method_setup ns_induct = 
    Scan.succeed (SIMPLE_METHOD' o ns_induct_tac)\
    "for inductive reasoning about the Needham-Schroeder protocol"

textConverts invariants into statements about reachable states
lemmas Always_Collect_reachableD =
     Always_includes_reachable [THEN subsetD, THEN CollectD]

textSpy never sees another agent's private key! (unless it's bad at start)
lemma Spy_see_priK:
     "Nprg \ Always {s. (Key (priK A) \ parts (spies s)) = (A \ bad)}"
apply ns_induct
apply blast
done
declare Spy_see_priK [THEN Always_Collect_reachableD, simp]

lemma Spy_analz_priK:
     "Nprg \ Always {s. (Key (priK A) \ analz (spies s)) = (A \ bad)}"
by (rule Always_reachable [THEN Always_weaken], auto)
declare Spy_analz_priK [THEN Always_Collect_reachableD, simp]


subsectionAuthenticity properties obtained from NS2

textIt is impossible to re-use a nonce in both NS1 and NS2 provided the
     nonce is secret.  (Honest users generate fresh nonces.)
lemma no_nonce_NS1_NS2:
 "Nprg
   Always {s. Crypt (pubK C) {NA', Nonce NA\ \ parts (spies s) -->
                Crypt (pubK B) {Nonce NA, Agent A}  parts (spies s) -->
                Nonce NA  analz (spies s)}"
apply ns_induct
apply (blast intro: analz_insertI)+
done

textAdding it to the claset slows down proofs...
lemmas no_nonce_NS1_NS2_reachable =
       no_nonce_NS1_NS2 [THEN Always_Collect_reachableD, rule_format]


textUnicity for NS1: nonce NA identifies agents A and B
lemma unique_NA_lemma:
     "Nprg
   Always {s. Nonce NA  analz (spies s) -->
                Crypt(pubK B) {Nonce NA, Agent A}  parts(spies s) -->
                Crypt(pubK B') \Nonce NA, Agent A'}  parts(spies s) -->
                A=A' & B=B'}"
apply ns_induct
apply auto
txtFake, NS1 are non-trivial
done

textUnicity for NS1: nonce NA identifies agents A and B
lemma unique_NA:
     "[| Crypt(pubK B) \Nonce NA, Agent A\ \ parts(spies s);
         Crypt(pubK B') \Nonce NA, Agent A'}  parts(spies s);
         Nonce NA  analz (spies s);
         s  reachable Nprg |]
      ==> A=A' & B=B'"
by (blast dest: unique_NA_lemma [THEN Always_Collect_reachableD])


textSecrecy: Spy does not see the nonce sent in msg NS1 if A and B are secure
lemma Spy_not_see_NA:
     "[| A \ bad; B \ bad |]
  ==> Nprg  Always
              {s. Says A B (Crypt(pubK B) {Nonce NA, Agent A} set s
                  --> Nonce NA  analz (spies s)}"
apply ns_induct
txtNS3
prefer 4 apply (blast intro: no_nonce_NS1_NS2_reachable)
txtNS2
prefer 3 apply (blast dest: unique_NA)
txtNS1
prefer 2 apply blast
txtFake
apply spy_analz
done


textAuthentication for A: if she receives message 2 and has used NA
  to start a run, then B has sent message 2.
lemma A_trusts_NS2:
 "[| A \ bad; B \ bad |]
  ==> Nprg  Always
              {s. Says A B (Crypt(pubK B) {Nonce NA, Agent A} set s &
                  Crypt(pubK A) {Nonce NA, Nonce NB}  parts (knows Spy s)
         --> Says B A (Crypt(pubK A) {Nonce NA, Nonce NB} set s}"
  (*insert an invariant for use in some of the subgoals*)
apply (insert Spy_not_see_NA [of A B NA], simp, ns_induct)
apply (auto dest: unique_NA)
done


textIf the encrypted message appears then it originated with Alice in NS1
lemma B_trusts_NS1:
     "Nprg \ Always
              {s. Nonce NA  analz (spies s) -->
                  Crypt (pubK B) {Nonce NA, Agent A}  parts (spies s)
         --> Says A B (Crypt (pubK B) {Nonce NA, Agent A} set s}"
apply ns_induct
apply blast
done


subsectionAuthenticity properties obtained from NS2

textUnicity for NS2: nonce NB identifies nonce NA and agent A.
   Proof closely follows that of unique_NA.
lemma unique_NB_lemma:
 "Nprg
   Always {s. Nonce NB  analz (spies s)  -->
                Crypt (pubK A) {Nonce NA, Nonce NB}  parts (spies s) -->
                Crypt(pubK A') \Nonce NA', Nonce NB}  parts(spies s) -->
                A=A' & NA=NA'}"
apply ns_induct
apply auto
txtFake, NS2 are non-trivial
done

lemma unique_NB:
     "[| Crypt(pubK A) \Nonce NA, Nonce NB\ \ parts(spies s);
         Crypt(pubK A') \Nonce NA', Nonce NB}  parts(spies s);
         Nonce NB  analz (spies s);
         s  reachable Nprg |]
      ==> A=A' & NA=NA'"
apply (blast dest: unique_NB_lemma [THEN Always_Collect_reachableD])
done


textNB remains secret PROVIDED Alice never responds with round 3
lemma Spy_not_see_NB:
     "[| A \ bad; B \ bad |]
  ==> Nprg  Always
              {s. Says B A (Crypt (pubK A) {Nonce NA, Nonce NB} set s &
                  (C. Says A C (Crypt (pubK C) (Nonce NB))  set s)
                  --> Nonce NB  analz (spies s)}"
apply ns_induct
apply (simp_all (no_asm_simp) add: all_conj_distrib)
txtNS3: because NB determines A
prefer 4 apply (blast dest: unique_NB)
txtNS2: by freshness and unicity of NB
prefer 3 apply (blast intro: no_nonce_NS1_NS2_reachable)
txtNS1: by freshness
prefer 2 apply blast
txtFake
apply spy_analz
done



textAuthentication for B: if he receives message 3 and has used NB
  in message 2, then A has sent message 3--to somebody....
lemma B_trusts_NS3:
     "[| A \ bad; B \ bad |]
  ==> Nprg  Always
              {s. Crypt (pubK B) (Nonce NB)  parts (spies s) &
                  Says B A  (Crypt (pubK A) {Nonce NA, Nonce NB} set s
                  --> (C. Says A C (Crypt (pubK C) (Nonce NB))  set s)}"
  (*insert an invariant for use in some of the subgoals*)
apply (insert Spy_not_see_NB [of A B NA NB], simp, ns_induct)
apply (simp_all (no_asm_simp) add: ex_disj_distrib)
apply auto
txtNS3: because NB determines A. This use of unique_NB is robust.
apply (blast intro: unique_NB [THEN conjunct1])
done


textCan we strengthen the secrecy theorem?  NO
lemma "[| A \ bad; B \ bad |]
  ==> Nprg  Always
              {s. Says B A (Crypt (pubK A) {Nonce NA, Nonce NB} set s
                  --> Nonce NB  analz (spies s)}"
apply ns_induct
apply auto
txtFake
apply spy_analz
txtNS2: by freshness and unicity of NB
 apply (blast intro: no_nonce_NS1_NS2_reachable)
txtNS3: unicity of NB identifies A and NA, but not B
apply (frule_tac A'=A in Says_imp_spies [THEN parts.Inj, THEN unique_NB])
apply (erule Says_imp_spies [THEN parts.Inj], auto)
apply (rename_tac s B' C)
txtThis is the attack!
@{subgoals[display,indent=0,margin=65]}

oops


(*
THIS IS THE ATTACK!
[| A \<notin> bad; B \<notin> bad |]
==> Nprg
   \<in> Always
       {s. Says B A (Crypt (pubK A) \<lbrace>Nonce NA, Nonce NB\<rbrace>) \<in> set s -->
           Nonce NB \<notin> analz (knows Spy s)}
 1. !!s B' C.
       [| A \<notin> bad; B \<notin> bad; s \<in> reachable Nprg
          Says A C (Crypt (pubK C) \<lbrace>Nonce NA, Agent A\<rbrace>) \<in> set s;
          Says B' A (Crypt (pubK A) \<lbrace>Nonce NA, Nonce NB\<rbrace>) \<in> set s;
          C \<in> bad; Says B A (Crypt (pubK A) \<lbrace>Nonce NA, Nonce NB\<rbrace>) \<in> set s;
          Nonce NB \<notin> analz (knows Spy s) |]
       ==> False
*)


end

Messung V0.5
C=93 H=100 G=96

¤ Dauer der Verarbeitung: 0.8 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.