Theory m2_confid_chan
section ‹Refinement 2b: Confidential Channel Protocol›
theory m2_confid_chan imports m1_auth "../Refinement/Channels"
begin
text ‹We refine the abstract authentication protocol to the first two
steps of the Needham-Schroeder-Lowe protocol, which we call NSL/2.
In standard protocol notation, the original protocol is specified as follows.
\[
\begin{array}{llll}
\mathrm{M1.} & A \rightarrow B & : & \{N_A, A\}_{K(B)} \\
\mathrm{M2.} & B \rightarrow A & : & \{N_A, N_B, B\}_{K(A)}
\end{array}
\]
At this refinement level, we abstract the encrypted messages to
non-cryptographic messages transmitted on confidential channels.›
declare domIff [simp, iff del]
subsection ‹State and observations›
record m2_state = m1_state +
chan :: "chmsg set"
type_synonym
m2_obs = m1_state
definition
m2_obs :: "m2_state ⇒ m2_obs" where
"m2_obs s ≡ ⦇
runs = runs s
⦈"
subsection ‹Events›
definition
m2_init :: "m2_state set"
where
"m2_init ≡ { ⦇
runs = Map.empty,
chan = {}
⦈ }"
definition
m2_step1 :: "[rid_t, agent, agent, nonce] ⇒ (m2_state × m2_state) set"
where
"m2_step1 Ra A B Na ≡ {(s, s1).
Ra ∉ dom (runs s) ∧
Na = Ra$0 ∧
s1 = s⦇
runs := (runs s)(Ra ↦ (Init, [A, B], [])),
chan := insert (Confid A B (Msg [aNon Na])) (chan s)
⦈
}"
definition
m2_step2 :: "[rid_t, agent, agent, nonce, nonce] ⇒ (m2_state × m2_state) set"
where
"m2_step2 Rb A B Na Nb ≡ {(s, s1).
Rb ∉ dom (runs s) ∧
Nb = Rb$0 ∧
Confid A B (Msg [aNon Na]) ∈ chan s ∧
s1 = s⦇
runs := (runs s)(Rb ↦ (Resp, [A, B], [aNon Na])),
chan := insert (Confid B A (Msg [aNon Na, aNon Nb])) (chan s)
⦈
}"
definition
m2_step3 :: "[rid_t, agent, agent, nonce, nonce] ⇒ (m2_state × m2_state) set"
where
"m2_step3 Ra A B Na Nb ≡ {(s, s1).
runs s Ra = Some (Init, [A, B], []) ∧
Na = Ra$0 ∧
Confid B A (Msg [aNon Na, aNon Nb]) ∈ chan s ∧
s1 = s⦇
runs := (runs s)(Ra ↦ (Init, [A, B], [aNon Nb]))
⦈
}"
text ‹Intruder fake event.›
definition
m2_fake :: "(m2_state × m2_state) set"
where
"m2_fake ≡ {(s, s1).
s1 = s⦇ chan := fake ik0 (dom (runs s)) (chan s) ⦈
}"
text ‹Transition system.›
definition
m2_trans :: "(m2_state × m2_state) set" where
"m2_trans ≡ (⋃ A B Ra Rb Na Nb.
m2_step1 Ra A B Na ∪
m2_step2 Rb A B Na Nb ∪
m2_step3 Ra A B Na Nb ∪
m2_fake ∪
Id
)"
definition
m2 :: "(m2_state, m2_obs) spec" where
"m2 ≡ ⦇
init = m2_init,
trans = m2_trans,
obs = m2_obs
⦈"
lemmas m2_defs =
m2_def m2_init_def m2_trans_def m2_obs_def
m2_step1_def m2_step2_def m2_step3_def m2_fake_def
subsection ‹Invariants›
subsubsection ‹Invariant 1: Messages only contains generated nonces.›
definition
m2_inv1_nonces :: "m2_state set" where
"m2_inv1_nonces ≡ {s. ∀R.
aNon (R$0) ∈ atoms (chan s) ⟶ R ∈ dom (runs s)
}"
lemmas m2_inv1_noncesI =
m2_inv1_nonces_def [THEN setc_def_to_intro, rule_format]
lemmas m2_inv1_noncesE [elim] =
m2_inv1_nonces_def [THEN setc_def_to_elim, rule_format]
lemmas m2_inv1_noncesD =
m2_inv1_nonces_def [THEN setc_def_to_dest, rule_format, rotated 1]
lemma PO_m2_inv1_init [iff]: "init m2 ⊆ m2_inv1_nonces"
by (auto simp add: PO_hoare_def m2_defs intro!: m2_inv1_noncesI)
lemma PO_m2_inv1_trans [iff]:
"{m2_inv1_nonces} trans m2 {> m2_inv1_nonces}"
apply (auto simp add: PO_hoare_def m2_defs intro!: m2_inv1_noncesI)
apply (auto dest: m2_inv1_noncesD)
apply (subgoal_tac "aNon (R$0) ∈ atoms (chan xa)", auto)
done
lemma PO_m2_inv012 [iff]:
"reach m2 ⊆ m2_inv1_nonces"
by (rule inv_rule_basic) (auto)
subsubsection ‹Invariant 3: relates message 2 with the responder run›
text ‹It is needed, together with initiator nonce secrecy, in proof
obligation REF/@{term m2_step2}.›
definition
m2_inv3_msg2 :: "m2_state set" where
"m2_inv3_msg2 ≡ {s. ∀A B Na Nb.
Confid B A (Msg [aNon Na, aNon Nb]) ∈ chan s ⟶
aNon Na ∉ extr ik0 (chan s) ⟶
(∃Rb. Nb = Rb$0 ∧ runs s Rb = Some (Resp, [A, B], [aNon Na]))
}"
lemmas m2_inv3_msg2I = m2_inv3_msg2_def [THEN setc_def_to_intro, rule_format]
lemmas m2_inv3_msg2E [elim] = m2_inv3_msg2_def [THEN setc_def_to_elim, rule_format]
lemmas m2_inv3_msg2D = m2_inv3_msg2_def [THEN setc_def_to_dest, rule_format, rotated 1]
lemma PO_m2_inv4_init [iff]:
"init m2 ⊆ m2_inv3_msg2"
by (auto simp add: PO_hoare_def m2_defs intro!: m2_inv3_msg2I)
lemma PO_m2_inv4_trans [iff]:
"{m2_inv3_msg2} trans m2 {> m2_inv3_msg2}"
apply (auto simp add: PO_hoare_def m2_defs intro!: m2_inv3_msg2I)
apply (auto dest: m2_inv3_msg2D dom_lemmas)
apply (drule m2_inv3_msg2D, auto dest: dom_lemmas)
apply (drule m2_inv3_msg2D, auto, force)
done
lemma PO_m2_inv4 [iff]: "reach m2 ⊆ m2_inv3_msg2"
by (rule inv_rule_incr) (auto del: subsetI)
subsubsection ‹Invariant 4: Initiator nonce secrecy.›
text ‹It is needed in the proof
obligation REF/@{term m2_step2}. It would be sufficient to prove the invariant
for the case @{term "x=None"}, but we have generalized it here.›
definition
m2_inv4_inon_secret :: "m2_state set" where
"m2_inv4_inon_secret ≡ {s. ∀A B Ra al.
runs s Ra = Some (Init, [A, B], al) ⟶
A ∉ bad ⟶ B ∉ bad ⟶
aNon (Ra$0) ∉ extr ik0 (chan s)
}"
lemmas m2_inv4_inon_secretI =
m2_inv4_inon_secret_def [THEN setc_def_to_intro, rule_format]
lemmas m2_inv4_inon_secretE [elim] =
m2_inv4_inon_secret_def [THEN setc_def_to_elim, rule_format]
lemmas m2_inv4_inon_secretD =
m2_inv4_inon_secret_def [THEN setc_def_to_dest, rule_format, rotated 1]
lemma PO_m2_inv3_init [iff]:
"init m2 ⊆ m2_inv4_inon_secret"
by (auto simp add: PO_hoare_def m2_defs intro!: m2_inv4_inon_secretI)
lemma PO_m2_inv3_trans [iff]:
"{m2_inv4_inon_secret ∩ m2_inv1_nonces}
trans m2
{> m2_inv4_inon_secret}"
apply (auto simp add: PO_hoare_def m2_defs intro!: m2_inv4_inon_secretI)
apply (auto dest: m2_inv4_inon_secretD)
apply (fastforce)
apply (fastforce)
apply (fastforce)
done
lemma PO_m2_inv3 [iff]: "reach m2 ⊆ m2_inv4_inon_secret"
by (rule inv_rule_incr [where J="m2_inv1_nonces"]) (auto)
subsection ‹Refinement›
definition
R12 :: "(m1_state × m2_state) set" where
"R12 ≡ {(s, t). runs s = runs t}"
abbreviation
med21 :: "m2_obs ⇒ m1_obs" where
"med21 ≡ id"
text ‹Proof obligations.›
lemma PO_m2_step1_refines_m1_step1:
"{R12}
(m1_step1 Ra A B Na), (m2_step1 Ra A B Na)
{> R12}"
by (auto simp add: PO_rhoare_defs R12_def m1_defs m2_defs)
lemma PO_m2_step2_refines_m1_step2:
"{R12}
(m1_step2 Rb A B Na Nb), (m2_step2 Rb A B Na Nb)
{> R12}"
by (auto simp add: PO_rhoare_defs R12_def m1_defs m2_defs)
lemma PO_m2_step3_refines_m1_step3:
"{R12 ∩ UNIV × (m2_inv4_inon_secret ∩ m2_inv3_msg2)}
(m1_step3 Ra A B Na Nb), (m2_step3 Ra A B Na Nb)
{> R12}"
by (auto simp add: PO_rhoare_defs R12_def m1_defs m2_defs)
(blast)
text ‹New fake events refine skip.›
lemma PO_m2_fake_refines_skip:
"{R12} Id, m2_fake {> R12}"
by (auto simp add: PO_rhoare_def R12_def m1_defs m2_defs)
lemmas PO_m2_trans_refines_m1_trans =
PO_m2_step1_refines_m1_step1 PO_m2_step2_refines_m1_step2
PO_m2_step3_refines_m1_step3 PO_m2_fake_refines_skip
text ‹All together now...›
lemma PO_m2_refines_init_m1 [iff]:
"init m2 ⊆ R12``(init m1)"
by (auto simp add: R12_def m1_defs m2_defs)
lemma PO_m2_refines_trans_m1 [iff]:
"{R12 ∩
UNIV × (m2_inv4_inon_secret ∩ m2_inv3_msg2)}
(trans m1), (trans m2)
{> R12}"
apply (auto simp add: m2_def m2_trans_def m1_def m1_trans_def)
apply (blast intro!: PO_m2_trans_refines_m1_trans)+
done
lemma PO_R12_obs_consistent [iff]:
"obs_consistent R12 med21 m1 m2"
by (auto simp add: obs_consistent_def R12_def m1_defs m2_defs)
lemma PO_m3_refines_m2:
"refines
(R12 ∩
UNIV × (m2_inv4_inon_secret ∩ m2_inv3_msg2 ∩ m2_inv1_nonces))
med21 m1 m2"
by (rule Refinement_using_invariants) (auto)
end