section‹Analyzing the Needham-Schroeder Public-Key Protocol in UNITY›
theory NSP_Bad imports"HOL-Auth.Public""../UNITY_Main"begin
text‹This is the flawed version, vulnerable to Lowe's attack.
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 inventnewnonceshere,buthecanalsouseNS1.Commonto
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)"
text\<open>AuthenticationforA:ifshereceivesmessage2andhasusedNA tostartarun,thenBhassentmessage2.\<close> lemmaA_trusts_NS2: "[|A\<notin>bad;B\<notin>bad|] ==>Nprg\<in>Always {s.SaysAB(Crypt(pubKB)\<lbrace>NonceNA,AgentA\<rbrace>)\<in>sets& Crypt(pubKA)\<lbrace>NonceNA,NonceNB\<rbrace>\<in>parts(knowsSpys) -->SaysBA(Crypt(pubKA)\<lbrace>NonceNA,NonceNB\<rbrace>)\<in>sets}"
(*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
text‹If 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
subsection‹Authenticity properties obtained from NS2›
text‹Unicity 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 txt‹Fake, NS2 are non-trivial› done
text‹NB 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) txt‹NS3: because NB determines A› prefer4apply (blast dest: unique_NB) txt‹NS2: by freshness and unicity of NB› prefer3apply (blast intro: no_nonce_NS1_NS2_reachable) txt‹NS1: by freshness› prefer2apply blast txt‹Fake› apply spy_analz done
text‹Authentication 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 txt‹NS3: because NB determines A. This use of ‹unique_NB› is robust.› apply (blast intro: unique_NB [THEN conjunct1]) done
text‹Can 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 txt‹Fake› apply spy_analz txt‹NS2: by freshness and unicity of NB› apply (blast intro: no_nonce_NS1_NS2_reachable) txt‹NS3: 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) txt‹This is the attack!
{subgoals[display,indent=0,margin=65]} › oops
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.