(* Title: HOL/Auth/Kerberos_BAN.thy
Author: Giampaolo Bella, Cambridge University Computer Laboratory
Copyright 1998 University of Cambridge
*)
section‹The Kerberos Protocol, BAN Version
›
theory Kerberos_BAN
imports Public
begin
text‹From page 251 of
Burrows, Abadi
and Needham (1989). A Logic of Authentication.
Proc. Royal Soc. 426
Confidentiality (secrecy)
and authentication properties are
also
given
in a termporal version: strong guarantees
in a little abstracted
- but very realistic - model.
›
(* Temporal model of accidents: session keys can be leaked
ONLY when they have expired *)
consts
(*Duration of the session key*)
sesKlife :: nat
(*Duration of the authenticator*)
authlife :: nat
text‹The ticket should remain fresh
for two journeys on the network at least
›
specification (sesKlife)
sesKlife_LB [iff]:
"2 \ sesKlife"
by blast
text‹The authenticator only
for one journey
›
specification (authlife)
authlife_LB [iff]:
"authlife \ 0"
by blast
abbreviation
CT ::
"event list \ nat" where
"CT == length "
abbreviation
expiredK ::
"[nat, event list] \ bool" where
"expiredK T evs == sesKlife + T < CT evs"
abbreviation
expiredA ::
"[nat, event list] \ bool" where
"expiredA T evs == authlife + T < CT evs"
definition
(* A is the true creator of X if she has sent X and X never appeared on
the trace before this event. Recall that traces grow from head. *)
Issues ::
"[agent, agent, msg, event list] \ bool"
(
‹_ Issues _
with _ on _
›)
where
"A Issues B with X on evs =
(
∃Y. Says A B Y
∈ set evs
∧ X
∈ parts {Y}
∧
X
∉ parts (spies (takeWhile (λz. z
≠ Says A B Y) (rev evs))))
"
definition
(* Yields the subtrace of a given trace from its beginning to a given event *)
before ::
"[event, event list] \ event list" (
‹before _ on _
›)
where "before ev on evs = takeWhile (\z. z \ ev) (rev evs)"
definition
(* States than an event really appears only once on a trace *)
Unique ::
"[event, event list] \ bool" (
‹Unique _ on _
›)
where "Unique ev on evs = (ev \ set (tl (dropWhile (\z. z \ ev) evs)))"
inductive_set bankerberos ::
"event list set"
where
Nil:
"[] \ bankerberos"
| Fake:
"\ evsf \ bankerberos; X \ synth (analz (spies evsf)) \
==> Says Spy B X # evsf
∈ bankerberos
"
| BK1:
"\ evs1 \ bankerberos \
==> Says A Server
{Agent A, Agent B
} # evs1
∈ bankerberos
"
| BK2:
"\ evs2 \ bankerberos; Key K \ used evs2; K \ symKeys;
Says A
' Server \Agent A, Agent B\ \ set evs2 \
==> Says Server A
(Crypt (shrK A)
{Number (CT evs2), Agent B, Key K,
(Crypt (shrK B)
{Number (CT evs2), Agent A, Key K
})
})
# evs2
∈ bankerberos
"
| BK3:
"\ evs3 \ bankerberos;
Says S A (Crypt (shrK A)
{Number Tk, Agent B, Key K, Ticket
})
∈ set evs3;
Says A Server
{Agent A, Agent B
} ∈ set evs3;
¬ expiredK Tk evs3
]
==> Says A B
{Ticket, Crypt K
{Agent A, Number (CT evs3)
} }
# evs3
∈ bankerberos
"
| BK4:
"\ evs4 \ bankerberos;
Says A
' B \(Crypt (shrK B) \Number Tk, Agent A, Key K\),
(Crypt K
{Agent A, Number Ta
})
} ∈ set evs4;
¬ expiredK Tk evs4;
¬ expiredA Ta evs4
]
==> Says B A (Crypt K (Number Ta)) # evs4
∈ bankerberos
"
(*Old session keys may become compromised*)
|
Oops:
"\ evso \ bankerberos;
Says Server A (Crypt (shrK A)
{Number Tk, Agent B, Key K, Ticket
})
∈ set evso;
expiredK Tk evso
]
==> Notes Spy
{Number Tk, Key K
} # evso
∈ bankerberos
"
declare Says_imp_knows_Spy [
THEN parts.Inj, dest]
declare parts.Body [dest]
declare analz_into_parts [dest]
declare Fake_parts_insert_in_Un [dest]
text‹A
"possibility property": there are traces that reach the
end.
›
lemma "\Key K \ used []; K \ symKeys\
==> ∃Timestamp.
∃evs
∈ bankerberos.
Says B A (Crypt K (Number Timestamp))
∈ set evs
"
apply (cut_tac sesKlife_LB)
apply (intro exI bexI)
apply (rule_tac [2]
bankerberos.Nil [
THEN bankerberos.BK1,
THEN bankerberos.BK2,
THEN bankerberos.BK3,
THEN bankerberos.BK4])
apply (possibility, simp_all (no_asm_simp) add: used_Cons)
done
subsection‹Lemmas for reasoning about predicate
"Issues"›
lemma spies_Says_rev:
"spies (evs @ [Says A B X]) = insert X (spies evs)"
apply (induct_tac
"evs")
apply (rename_tac [2] a b)
apply (induct_tac [2]
"a", auto)
done
lemma spies_Gets_rev:
"spies (evs @ [Gets A X]) = spies evs"
apply (induct_tac
"evs")
apply (rename_tac [2] a b)
apply (induct_tac [2]
"a", auto)
done
lemma spies_Notes_rev:
"spies (evs @ [Notes A X]) =
(
if A
∈bad
then insert X (spies evs) else spies evs)
"
apply (induct_tac
"evs")
apply (rename_tac [2] a b)
apply (induct_tac [2]
"a", auto)
done
lemma spies_evs_rev:
"spies evs = spies (rev evs)"
apply (induct_tac
"evs")
apply (rename_tac [2] a b)
apply (induct_tac [2]
"a")
apply (simp_all (no_asm_simp) add: spies_Says_rev spies_Gets_rev spies_Notes_rev)
done
lemmas parts_spies_evs_revD2 = spies_evs_rev [
THEN equalityD2,
THEN parts_mono]
lemma spies_takeWhile:
"spies (takeWhile P evs) \ spies evs"
apply (induct_tac
"evs")
apply (rename_tac [2] a b)
apply (induct_tac [2]
"a", auto)
txt‹Resembles
‹used_subset_append
› in theory Event.
›
done
lemmas parts_spies_takeWhile_mono = spies_takeWhile [
THEN parts_mono]
text‹Lemmas for reasoning about predicate
"before"›
lemma used_Says_rev:
"used (evs @ [Says A B X]) = parts {X} \ (used evs)"
apply (induct_tac
"evs")
apply simp
apply (rename_tac a b)
apply (induct_tac
"a")
apply auto
done
lemma used_Notes_rev:
"used (evs @ [Notes A X]) = parts {X} \ (used evs)"
apply (induct_tac
"evs")
apply simp
apply (rename_tac a b)
apply (induct_tac
"a")
apply auto
done
lemma used_Gets_rev:
"used (evs @ [Gets B X]) = used evs"
apply (induct_tac
"evs")
apply simp
apply (rename_tac a b)
apply (induct_tac
"a")
apply auto
done
lemma used_evs_rev:
"used evs = used (rev evs)"
apply (induct_tac
"evs")
apply simp
apply (rename_tac a b)
apply (induct_tac
"a")
apply (simp add: used_Says_rev)
apply (simp add: used_Gets_rev)
apply (simp add: used_Notes_rev)
done
lemma used_takeWhile_used [rule_format]:
"x \ used (takeWhile P X) \ x \ used X"
apply (induct_tac
"X")
apply simp
apply (rename_tac a b)
apply (induct_tac
"a")
apply (simp_all add: used_Nil)
apply (blast dest!: initState_into_used)+
done
lemma set_evs_rev:
"set evs = set (rev evs)"
apply auto
done
lemma takeWhile_void [rule_format]:
"x \ set evs \ takeWhile (\z. z \ x) evs = evs"
apply auto
done
(**** Inductive proofs about bankerberos ****)
text‹Forwarding
Lemma for reasoning about the encrypted portion of message BK3
›
lemma BK3_msg_in_parts_spies:
"Says S A (Crypt KA \Timestamp, B, K, X\) \ set evs
==> X
∈ parts (spies evs)
"
apply blast
done
lemma Oops_parts_spies:
"Says Server A (Crypt (shrK A) \Timestamp, B, K, X\) \ set evs
==> K
∈ parts (spies evs)
"
apply blast
done
text‹Spy never sees another agent
's shared key! (unless it's bad at start)
›
lemma Spy_see_shrK [simp]:
"evs \ bankerberos \ (Key (shrK A) \ parts (spies evs)) = (A \ bad)"
apply (erule bankerberos.induct)
apply (frule_tac [7] Oops_parts_spies)
apply (frule_tac [5] BK3_msg_in_parts_spies, simp_all, blast+)
done
lemma Spy_analz_shrK [simp]:
"evs \ bankerberos \ (Key (shrK A) \ analz (spies evs)) = (A \ bad)"
apply auto
done
lemma Spy_see_shrK_D [dest!]:
"\ Key (shrK A) \ parts (spies evs);
evs
∈ bankerberos
] ==> A
∈bad
"
apply (blast dest: Spy_see_shrK)
done
lemmas Spy_analz_shrK_D = analz_subset_parts [
THEN subsetD,
THEN Spy_see_shrK_D, dest!]
text‹Nobody can
have used non-existent keys!
›
lemma new_keys_not_used [simp]:
"\Key K \ used evs; K \ symKeys; evs \ bankerberos\
==> K
∉ keysFor (parts (spies evs))
"
apply (erule rev_mp)
apply (erule bankerberos.induct)
apply (frule_tac [7] Oops_parts_spies)
apply (frule_tac [5] BK3_msg_in_parts_spies, simp_all)
txt‹Fake
›
apply (force dest!: keysFor_parts_insert)
txt‹BK2, BK3, BK4
›
apply (force dest!: analz_shrK_Decrypt)+
done
subsection‹Lemmas concerning the form of items passed
in messages
›
text‹Describes the form of K, X
and K
' when the Server sends this message.\
lemma Says_Server_message_form:
"\ Says Server A (Crypt K' \Number Tk, Agent B, Key K, Ticket\)
∈ set evs; evs
∈ bankerberos
]
==> K
' = shrK A \ K \ range shrK \
Ticket = (Crypt (shrK B)
{Number Tk, Agent A, Key K
})
∧
Key K
∉ used(before
Says Server A (Crypt K
' \Number Tk, Agent B, Key K, Ticket\)
on evs)
∧
Tk = CT(before
Says Server A (Crypt K
' \Number Tk, Agent B, Key K, Ticket\)
on evs)
"
unfolding before_def
apply (erule rev_mp)
apply (erule bankerberos.induct, simp_all add: takeWhile_tail)
apply auto
apply (metis length_rev set_rev takeWhile_void used_evs_rev)+
done
text‹If the encrypted message appears
then it originated
with the Server
PROVIDED that A
is NOT compromised!
This allows A
to verify freshness of the session key.
›
lemma Kab_authentic:
"\ Crypt (shrK A) \Number Tk, Agent B, Key K, X\
∈ parts (spies evs);
A
∉ bad; evs
∈ bankerberos
]
==> Says Server A (Crypt (shrK A)
{Number Tk, Agent B, Key K, X
})
∈ set evs
"
apply (erule rev_mp)
apply (erule bankerberos.induct)
apply (frule_tac [7] Oops_parts_spies)
apply (frule_tac [5] BK3_msg_in_parts_spies, simp_all, blast)
done
text‹If the TICKET appears
then it originated
with the Server
›
text‹FRESHNESS OF THE SESSION KEY
to B
›
lemma ticket_authentic:
"\ Crypt (shrK B) \Number Tk, Agent A, Key K\ \ parts (spies evs);
B
∉ bad; evs
∈ bankerberos
]
==> Says Server A
(Crypt (shrK A)
{Number Tk, Agent B, Key K,
Crypt (shrK B)
{Number Tk, Agent A, Key K
}})
∈ set evs
"
apply (erule rev_mp)
apply (erule bankerberos.induct)
apply (frule_tac [7] Oops_parts_spies)
apply (frule_tac [5] BK3_msg_in_parts_spies, simp_all, blast)
done
text‹EITHER describes the form of X when the following message
is sent,
OR reduces it
to the Fake
case.
Use ‹Says_Server_message_form
› if applicable.
›
lemma Says_S_message_form:
"\ Says S A (Crypt (shrK A) \Number Tk, Agent B, Key K, X\)
∈ set evs;
evs
∈ bankerberos
]
==> (K
∉ range shrK
∧ X = (Crypt (shrK B)
{Number Tk, Agent A, Key K
}))
| X
∈ analz (spies evs)
"
apply (case_tac
"A \ bad")
apply (force dest!: Says_imp_spies [
THEN analz.Inj])
apply (frule Says_imp_spies [
THEN parts.Inj])
apply (blast dest!: Kab_authentic Says_Server_message_form)
done
(****
The following is to prove theorems of the form
Key K \<in> analz (insert (Key KAB) (spies evs)) \<Longrightarrow>
Key K \<in> analz (spies evs)
A more general formula must be proved inductively.
****)
text‹Session keys are not used
to encrypt other session keys
›
lemma analz_image_freshK [rule_format (no_asm)]:
"evs \ bankerberos \
∀K KK. KK
⊆ - (range shrK)
⟶
(Key K
∈ analz (Key`KK
∪ (spies evs))) =
(K
∈ KK | Key K
∈ analz (spies evs))
"
apply (erule bankerberos.induct)
apply (drule_tac [7] Says_Server_message_form)
apply (erule_tac [5] Says_S_message_form [
THEN disjE], analz_freshK, spy_analz, auto)
done
lemma analz_insert_freshK:
"\ evs \ bankerberos; KAB \ range shrK \ \
(Key K
∈ analz (insert (Key KAB) (spies evs))) =
(K = KAB | Key K
∈ analz (spies evs))
"
apply (simp only: analz_image_freshK analz_image_freshK_simps)
done
text‹The session key K uniquely identifies the message
›
lemma unique_session_keys:
"\ Says Server A
(Crypt (shrK A)
{Number Tk, Agent B, Key K, X
})
∈ set evs;
Says Server A
'
(Crypt (shrK A
') \Number Tk', Agent B
', Key K, X'})
∈ set evs;
evs
∈ bankerberos
] ==> A=A
' \ Tk=Tk' ∧ B=B
' \ X = X'"
apply (erule rev_mp)
apply (erule rev_mp)
apply (erule bankerberos.induct)
apply (frule_tac [7] Oops_parts_spies)
apply (frule_tac [5] BK3_msg_in_parts_spies, simp_all)
txt‹BK2: it can
't be a new key\
apply blast
done
lemma Server_Unique:
"\ Says Server A
(Crypt (shrK A)
{Number Tk, Agent B, Key K, Ticket
})
∈ set evs;
evs
∈ bankerberos
] ==>
Unique Says Server A (Crypt (shrK A)
{Number Tk, Agent B, Key K, Ticket
})
on evs
"
apply (erule rev_mp, erule bankerberos.induct, simp_all add: Unique_def)
apply blast
done
subsection‹Non-temporal guarantees, explicitly relying on non-occurrence of
oops events - refined below
by temporal guarantees
›
text‹Non temporal treatment of confidentiality
›
text‹Lemma: the session key sent
in msg BK2 would be lost
by oops
if the spy could see it!
›
lemma lemma_conf [rule_format (no_asm)]:
"\ A \ bad; B \ bad; evs \ bankerberos \
==> Says Server A
(Crypt (shrK A)
{Number Tk, Agent B, Key K,
Crypt (shrK B)
{Number Tk, Agent A, Key K
}})
∈ set evs
⟶
Key K
∈ analz (spies evs)
⟶ Notes Spy
{Number Tk, Key K
} ∈ set evs
"
apply (erule bankerberos.induct)
apply (frule_tac [7] Says_Server_message_form)
apply (frule_tac [5] Says_S_message_form [
THEN disjE])
apply (simp_all (no_asm_simp) add: analz_insert_eq analz_insert_freshK pushes)
txt‹Fake
›
apply spy_analz
txt‹BK2
›
apply (blast intro: parts_insertI)
txt‹BK3
›
apply (case_tac
"Aa \ bad")
prefer 2
apply (blast dest: Kab_authentic unique_session_keys)
apply (blast dest: Says_imp_spies [
THEN analz.Inj] Crypt_Spy_analz_bad elim!: MPair_anal
z)
txt‹Oops›
apply (blast dest: unique_session_keys)
done
text‹Confidentiality for the Server: Spy does not see the keys sent in msg BK2
as long as they have not expired.›
lemma Confidentiality_S:
"\ Says Server A
(Crypt K' \Number Tk, Agent B, Key K, Ticket\) \ set evs;
Notes Spy {Number Tk, Key K} ∉ set evs;
A ∉ bad; B ∉ bad; evs ∈ bankerberos
] ==> Key K ∉ analz (spies evs)"
apply (frule Says_Server_message_form, assumption)
apply (blast intro: lemma_conf)
done
text‹Confidentiality for Alice›
lemma Confidentiality_A:
"\ Crypt (shrK A) \Number Tk, Agent B, Key K, X\ \ parts (spies evs);
Notes Spy {Number Tk, Key K} ∉ set evs;
A ∉ bad; B ∉ bad; evs ∈ bankerberos
] ==> Key K ∉ analz (spies evs)"
apply (blast dest!: Kab_authentic Confidentiality_S)
done
text‹Confidentiality for Bob›
lemma Confidentiality_B:
"\ Crypt (shrK B) \Number Tk, Agent A, Key K\
∈ parts (spies evs);
Notes Spy {Number Tk, Key K} ∉ set evs;
A ∉ bad; B ∉ bad; evs ∈ bankerberos
] ==> Key K ∉ analz (spies evs)"
apply (blast dest!: ticket_authentic Confidentiality_S)
done
text‹Non temporal treatment of authentication›
text‹Lemmas ‹lemma_A› and ‹lemma_B› in fact are common to both temporal and non-temporal treatments›
lemma lemma_A [rule_format]:
"\ A \ bad; B \ bad; evs \ bankerberos \
==>
Key K ∉ analz (spies evs) ⟶
Says Server A (Crypt (shrK A) {Number Tk, Agent B, Key K, X})
∈ set evs ⟶
Crypt K {Agent A, Number Ta} ∈ parts (spies evs) ⟶
Says A B {X, Crypt K {Agent A, Number Ta}}
∈ set evs"
apply (erule bankerberos.induct)
apply (frule_tac [7] Oops_parts_spies)
apply (frule_tac [5] Says_S_message_form)
apply (frule_tac [6] BK3_msg_in_parts_spies, analz_mono_contra)
apply (simp_all (no_asm_simp) add: all_conj_distrib)
txt‹Fake›
apply blast
txt‹BK2›
apply (force dest: Crypt_imp_invKey_keysFor)
txt‹BK3›
apply (blast dest: Kab_authentic unique_session_keys)
done
lemma lemma_B [rule_format]:
"\ B \ bad; evs \ bankerberos \
==> Key K ∉ analz (spies evs) ⟶
Says Server A (Crypt (shrK A) {Number Tk, Agent B, Key K, X})
∈ set evs ⟶
Crypt K (Number Ta) ∈ parts (spies evs) ⟶
Says B A (Crypt K (Number Ta)) ∈ set evs"
apply (erule bankerberos.induct)
apply (frule_tac [7] Oops_parts_spies)
apply (frule_tac [5] Says_S_message_form)
apply (drule_tac [6] BK3_msg_in_parts_spies, analz_mono_contra)
apply (simp_all (no_asm_simp) add: all_conj_distrib)
txt‹Fake›
apply blast
txt‹BK2›
apply (force dest: Crypt_imp_invKey_keysFor)
txt‹BK4›
apply (blast dest: ticket_authentic unique_session_keys
Says_imp_spies [THEN analz.Inj] Crypt_Spy_analz_bad)
done
text‹The "r" suffix indicates theorems where the confidentiality assumptions are relaxed by the corresponding arguments.›
text‹Authentication of A to B›
lemma B_authenticates_A_r:
"\ Crypt K \Agent A, Number Ta\ \ parts (spies evs);
Crypt (shrK B) {Number Tk, Agent A, Key K} ∈ parts (spies evs);
Notes Spy {Number Tk, Key K} ∉ set evs;
A ∉ bad; B ∉ bad; evs ∈ bankerberos ]
==> Says A B {Crypt (shrK B) {Number Tk, Agent A, Key K},
Crypt K {Agent A, Number Ta}} ∈ set evs"
apply (blast dest!: ticket_authentic
intro!: lemma_A
elim!: Confidentiality_S [THEN [2] rev_notE])
done
text‹Authentication of B to A›
lemma A_authenticates_B_r:
"\ Crypt K (Number Ta) \ parts (spies evs);
Crypt (shrK A) {Number Tk, Agent B, Key K, X} ∈ parts (spies evs);
Notes Spy {Number Tk, Key K} ∉ set evs;
A ∉ bad; B ∉ bad; evs ∈ bankerberos ]
==> Says B A (Crypt K (Number Ta)) ∈ set evs"
apply (blast dest!: Kab_authentic
intro!: lemma_B elim!: Confidentiality_S [THEN [2] rev_notE])
done
lemma B_authenticates_A:
"\ Crypt K \Agent A, Number Ta\ \ parts (spies evs);
Crypt (shrK B) {Number Tk, Agent A, Key K} ∈ parts (spies evs);
Key K ∉ analz (spies evs);
A ∉ bad; B ∉ bad; evs ∈ bankerberos ]
==> Says A B {Crypt (shrK B) {Number Tk, Agent A, Key K},
Crypt K {Agent A, Number Ta}} ∈ set evs"
apply (blast dest!: ticket_authentic intro!: lemma_A)
done
lemma A_authenticates_B:
"\ Crypt K (Number Ta) \ parts (spies evs);
Crypt (shrK A) {Number Tk, Agent B, Key K, X} ∈ parts (spies evs);
Key K ∉ analz (spies evs);
A ∉ bad; B ∉ bad; evs ∈ bankerberos ]
==> Says B A (Crypt K (Number Ta)) ∈ set evs"
apply (blast dest!: Kab_authentic intro!: lemma_B)
done
subsection‹Temporal guarantees, relying on a temporal check that insures that
no oops event occurred. These are available in the sense of goal availability›
text‹Temporal treatment of confidentiality›
text‹Lemma: the session key sent in msg BK2 would be EXPIRED
if the spy could see it!›
lemma lemma_conf_temporal [rule_format (no_asm)]:
"\ A \ bad; B \ bad; evs \ bankerberos \
==> Says Server A
(Crypt (shrK A) {Number Tk, Agent B, Key K,
Crypt (shrK B) {Number Tk, Agent A, Key K}})
∈ set evs ⟶
Key K ∈ analz (spies evs) ⟶ expiredK Tk evs"
apply (erule bankerberos.induct)
apply (frule_tac [7] Says_Server_message_form)
apply (frule_tac [5] Says_S_message_form [THEN disjE])
apply (simp_all (no_asm_simp) add: less_SucI analz_insert_eq analz_insert_freshK pushes)
txt‹Fake›
apply spy_analz
txt‹BK2›
apply (blast intro: parts_insertI less_SucI)
txt‹BK3›
apply (metis Crypt_Spy_analz_bad Kab_authentic Says_imp_analz_Spy
Says_imp_parts_knows_Spy analz.Snd less_SucI unique_session_keys)
txt‹Oops: PROOF FAILS if unsafe intro below›
apply (blast dest: unique_session_keys intro!: less_SucI)
done
text‹Confidentiality for the Server: Spy does not see the keys sent in msg BK2
as long as they have not expired.›
lemma Confidentiality_S_temporal:
"\ Says Server A
(Crypt K' \Number T, Agent B, Key K, X\) \ set evs;
¬ expiredK T evs;
A ∉ bad; B ∉ bad; evs ∈ bankerberos
] ==> Key K ∉ analz (spies evs)"
apply (frule Says_Server_message_form, assumption)
apply (blast intro: lemma_conf_temporal)
done
text‹Confidentiality for Alice›
lemma Confidentiality_A_temporal:
"\ Crypt (shrK A) \Number T, Agent B, Key K, X\ \ parts (spies evs);
¬ expiredK T evs;
A ∉ bad; B ∉ bad; evs ∈ bankerberos
] ==> Key K ∉ analz (spies evs)"
apply (blast dest!: Kab_authentic Confidentiality_S_temporal)
done
text‹Confidentiality for Bob›
lemma Confidentiality_B_temporal:
"\ Crypt (shrK B) \Number Tk, Agent A, Key K\
∈ parts (spies evs);
¬ expiredK Tk evs;
A ∉ bad; B ∉ bad; evs ∈ bankerberos
] ==> Key K ∉ analz (spies evs)"
apply (blast dest!: ticket_authentic Confidentiality_S_temporal)
done
text‹Temporal treatment of authentication›
text‹Authentication of A to B›
lemma B_authenticates_A_temporal:
"\ Crypt K \Agent A, Number Ta\ \ parts (spies evs);
Crypt (shrK B) {Number Tk, Agent A, Key K}
∈ parts (spies evs);
¬ expiredK Tk evs;
A ∉ bad; B ∉ bad; evs ∈ bankerberos ]
==> Says A B {Crypt (shrK B) {Number Tk, Agent A, Key K},
Crypt K {Agent A, Number Ta}} ∈ set evs"
apply (blast dest!: ticket_authentic
intro!: lemma_A
elim!: Confidentiality_S_temporal [THEN [2] rev_notE])
done
text‹Authentication of B to A›
lemma A_authenticates_B_temporal:
"\ Crypt K (Number Ta) \ parts (spies evs);
Crypt (shrK A) {Number Tk, Agent B, Key K, X}
∈ parts (spies evs);
¬ expiredK Tk evs;
A ∉ bad; B ∉ bad; evs ∈ bankerberos ]
==> Says B A (Crypt K (Number Ta)) ∈ set evs"
apply (blast dest!: Kab_authentic
intro!: lemma_B elim!: Confidentiality_S_temporal [THEN [2] rev_notE])
done
subsection‹Treatment of the key distribution goal using trace inspection. All
guarantees are in non-temporal form, hence non available, though their temporal
form is trivial to derive. These guarantees also convey a stronger form of
authentication - non-injective agreement on the session key›
lemma B_Issues_A:
"\ Says B A (Crypt K (Number Ta)) \ set evs;
Key K ∉ analz (spies evs);
A ∉ bad; B ∉ bad; evs ∈ bankerberos ]
==> B Issues A with (Crypt K (Number Ta)) on evs"
unfolding Issues_def
apply (rule exI)
apply (rule conjI, assumption)
apply (simp (no_asm))
apply (erule rev_mp)
apply (erule rev_mp)
apply (erule bankerberos.induct, analz_mono_contra)
apply (simp_all (no_asm_simp))
txt‹fake›
apply blast
txt‹K4 obviously is the non-trivial case›
apply (simp add: takeWhile_tail)
apply (blast dest: ticket_authentic parts_spies_takeWhile_mono [THEN subsetD] parts_spies_evs_revD2 [THEN subsetD] intro: A_authenticates_B_temporal)
done
lemma A_authenticates_and_keydist_to_B:
"\ Crypt K (Number Ta) \ parts (spies evs);
Crypt (shrK A) {Number Tk, Agent B, Key K, X} ∈ parts (spies evs);
Key K ∉ analz (spies evs);
A ∉ bad; B ∉ bad; evs ∈ bankerberos ]
==> B Issues A with (Crypt K (Number Ta)) on evs"
apply (blast dest!: A_authenticates_B B_Issues_A)
done
lemma A_Issues_B:
"\ Says A B \Ticket, Crypt K \Agent A, Number Ta\\
∈ set evs;
Key K ∉ analz (spies evs);
A ∉ bad; B ∉ bad; evs ∈ bankerberos ]
==> A Issues B with (Crypt K {Agent A, Number Ta}) on evs"
unfolding Issues_def
apply (rule exI)
apply (rule conjI, assumption)
apply (simp (no_asm))
apply (erule rev_mp)
apply (erule rev_mp)
apply (erule bankerberos.induct, analz_mono_contra)
apply (simp_all (no_asm_simp))
txt‹fake›
apply blast
txt‹K3 is the non trivial case›
apply (simp add: takeWhile_tail)
apply auto (*Technically unnecessary, merely clarifies the subgoal as it is presemted in the book*)
apply (blast dest: Kab_authentic Says_Server_message_form parts_spies_takeWhile_mono [THEN subsetD] parts_spies_evs_revD2 [THEN subsetD]
intro!: B_authenticates_A)
done
lemma B_authenticates_and_keydist_to_A:
"\ Crypt K \Agent A, Number Ta\ \ parts (spies evs);
Crypt (shrK B) {Number Tk, Agent A, Key K} ∈ parts (spies evs);
Key K ∉ analz (spies evs);
A ∉ bad; B ∉ bad; evs ∈ bankerberos ]
==> A Issues B with (Crypt K {Agent A, Number Ta}) on evs"
apply (blast dest: B_authenticates_A A_Issues_B)
done
end