Theory Channels

(*******************************************************************************

  Project: Development of Security Protocols by Refinement

  Module:  Refinement/Channels.thy (Isabelle/HOL 2016-1)
  ID:      $Id: Channels.thy 132773 2016-12-09 15:30:22Z csprenge $
  Author:  Christoph Sprenger, ETH Zurich <sprenger@inf.ethz.ch>
  
  Channel messages for Level 2 protocols

  Copyright (c) 2009-2016 Christoph Sprenger 
  Licence: LGPL

*******************************************************************************)

section ‹Channel Messages›

theory Channels imports Atoms
begin

(******************************************************************************)
subsection ‹Channel messages›
(******************************************************************************)

datatype secprop = auth | confid

type_synonym 
  chtyp = "secprop set"

abbreviation 
  secure :: chtyp where
  "secure  {auth, confid}"

datatype payload = Msg "atom list"
 
datatype chmsg = 
  StatCh "chtyp" "agent" "agent" "payload"
| DynCh "chtyp" "key" "payload" 


text ‹Abbreviations for use in protocol defs›

abbreviation 
  Insec :: "[agent, agent, payload]  chmsg" where
  "Insec  StatCh {}"

abbreviation 
  Confid :: "[agent, agent, payload]  chmsg" where
  "Confid  StatCh {confid}"

abbreviation 
  Auth :: "[agent, agent, payload]  chmsg" where
  "Auth  StatCh {auth}"

abbreviation 
  Secure :: "[agent, agent, payload]  chmsg" where
  "Secure  StatCh {auth, confid}"

abbreviation 
  dConfid :: "[key, payload]  chmsg" where
  "dConfid  DynCh {confid}"

abbreviation 
  dAuth :: "[key, payload]  chmsg" where
  "dAuth  DynCh {auth}"

abbreviation 
  dSecure :: "[key, payload]  chmsg" where
  "dSecure  DynCh {auth, confid}"


(******************************************************************************)
subsection ‹Keys used in dynamic channel messages›
(******************************************************************************)

definition 
  keys_for :: "chmsg set  key set" where
  "keys_for H  {K. c M. DynCh c K M  H}"

lemma keys_forI [dest]: "DynCh c K M  H  K  keys_for H"
by (auto simp add: keys_for_def)


lemma keys_for_empty [simp]: "keys_for {} = {}"
by (simp add: keys_for_def)

lemma keys_for_monotone: "G  H  keys_for G  keys_for H"
by (auto simp add: keys_for_def)

lemmas keys_for_mono [elim] = keys_for_monotone [THEN [2] rev_subsetD]


lemma keys_for_insert_StatCh [simp]: 
  "keys_for (insert (StatCh c A B M) H) = keys_for H"
by (auto simp add: keys_for_def)

lemma keys_for_insert_DynCh [simp]: 
  "keys_for (insert (DynCh c K M) H) = insert K (keys_for H)"
by (auto simp add: keys_for_def)


(******************************************************************************)
subsection ‹Atoms in a set of channel messages›
(******************************************************************************)

text ‹The set of atoms contained in a set of channel messages. We also 
include the public atoms, i.e., the agent names, numbers, and corrupted keys. 
›

inductive_set 
  atoms :: "chmsg set  atom set"
  for H :: "chmsg set"
where
  at_StatCh: " StatCh c A B (Msg M)  H; At  set M   At  atoms H"
| at_DynCh: " DynCh c K (Msg M)  H; At  set M   At  atoms H"

declare atoms.intros [intro]

lemma atoms_empty [simp]: "atoms {} = {}"
by (auto elim!: atoms.cases)

lemma atoms_monotone: "G  H  atoms G  atoms H"
by (auto elim!: atoms.cases)

lemmas atoms_mono [elim] = atoms_monotone [THEN [2] rev_subsetD]


lemma atoms_insert_StatCh [simp]: 
  "atoms (insert (StatCh c A B (Msg M)) H) = set M  atoms H"
by (auto elim!: atoms.cases)

lemma atoms_insert_DynCh [simp]: 
  "atoms (insert (DynCh c K (Msg M)) H) = set M  atoms H"
by (auto elim!: atoms.cases)


(******************************************************************************)
subsection ‹Intruder knowledge (atoms)›
(******************************************************************************)

text ‹Atoms that the intruder can extract from a set of channel messages.›

inductive_set 
  extr :: "atom set  chmsg set  atom set"
  for T :: "atom set" 
  and H :: "chmsg set"
where 
  extr_Inj: "At  T  At  extr T H"
| extr_StatCh: 
    " StatCh c A B (Msg M)  H; At  set M; confid  c  A  bad  B  bad  
    At  extr T H"
| extr_DynCh: 
    " DynCh c K (Msg M)  H; At  set M; confid  c  aKey K  extr T H  
    At  extr T H"

declare extr.intros [intro]
declare extr.cases [elim]


text‹Typical parameter describing initial intruder knowledge.›

definition
  ik0 :: "atom set" where 
  "ik0  range aAgt  range aNum  aKey`corrKey"

lemma ik0_aAgt [iff]: "aAgt A  ik0"
by (auto simp add: ik0_def)

lemma ik0_aNum [iff]: "aNum T  ik0"
by (auto simp add: ik0_def)

lemma ik0_aNon [iff]: "aNon N  ik0"
by (auto simp add: ik0_def)

lemma ik0_aKey_corr [simp]: "(aKey K  ik0) = (K  corrKey)"
by (auto simp add: ik0_def)


subsubsection ‹Basic lemmas›
(******************************************************************************)

lemma extr_empty [simp]: "extr T {} = T"
by (auto)

lemma extr_monotone [dest]: "G  H  extr T G  extr T H"
by (safe, erule extr.induct, auto)

lemmas extr_mono [elim] = extr_monotone [THEN [2] rev_subsetD]

lemma extr_monotone_param [dest]: "T  U  extr T H  extr U H"
by (safe, erule extr.induct, auto)

lemmas extr_mono_param [elim] = extr_monotone_param [THEN [2] rev_subsetD]

lemma extr_insert [intro]: "At  extr T H  At  extr T (insert C H)"
by (erule extr_mono) (auto)

lemma extr_into_atoms [dest]: "At  extr T H  At  T  atoms H"
by (erule extr.induct, auto)


subsubsection ‹Insertion lemmas for atom parameters›
(******************************************************************************)

lemma extr_insert_non_key_param [simp]:
  assumes "At  range aNon  range aAgt  range aNum"
  shows "extr (insert At T) H = insert At (extr T H)"
proof -
  { fix Bt
    assume "Bt  extr (insert At T) H"
    hence "Bt  insert At (extr T H)" 
      using assms by induct auto
  }
  thus ?thesis by auto
qed

lemma extr_insert_unused_key_param [simp]:
  assumes "K  keys_for H"
  shows "extr (insert (aKey K) T) H = insert (aKey K) (extr T H)"
proof -
  { fix At
    assume "At  extr (insert (aKey K) T) H"
    hence "At  insert (aKey K) (extr T H)" 
      using assms by induct (auto simp add: keys_for_def)
  }
  thus ?thesis by auto
qed



subsubsection ‹Insertion lemmas for each type of channel message›
(******************************************************************************)

text ‹Note that the parameter accumulates the extracted atoms. In particular, 
these may include keys that may open further dynamically confidential messages. 
›

lemma extr_insert_StatCh [simp]: 
  "extr T (insert (StatCh c A B (Msg M)) H) 
   = (if confid  c  A  bad  B  bad then extr (set M  T) H else extr T H)"
proof (cases "confid  c  A  bad  B  bad")
  case True
  moreover 
  {
    fix At
    assume "At  extr T (insert (StatCh c A B (Msg M)) H)"
    hence "At  extr (set M  T) H" by induct auto
  }
  moreover
  {
    fix At
    assume "At  extr (set M  T) H" 
    and    "confid  c  A  bad  B  bad"
    hence "At  extr T (insert (StatCh c A B (Msg M)) H)" by induct auto
  }
  ultimately show ?thesis by auto
next 
  case False
  moreover
  {
    fix At
    assume "At  extr T (insert (StatCh c A B (Msg M)) H)"
    and "confid  c" "A  bad" "B  bad"
    hence "At  extr T H" by induct auto
  }
  ultimately show ?thesis by auto
qed

lemma extr_insert_DynCh [simp]: 
  "extr T (insert (DynCh c K (Msg M)) H) 
   = (if confid  c  aKey K  extr T H then extr (set M  T) H else extr T H)"
proof (cases "confid  c  aKey K  extr T H")
  case True
  moreover
  {
    fix At
    assume "At  extr T (insert (DynCh c K (Msg M)) H)"
    hence "At  extr (set M  T) H" by induct auto
  }
  moreover
  {
    fix At
    assume "At  extr (set M  T) H"
    hence "At  extr T (insert (DynCh c K (Msg M)) H)" 
      using True by induct auto
  }
  ultimately show ?thesis by auto
next
  case False
  moreover
  hence "extr T (insert (DynCh c K (Msg M)) H) = extr T H" 
    by (intro equalityI subsetI) (erule extr.induct, auto)+
  ultimately show ?thesis by auto
qed


declare extr.cases [rule del, elim]


(******************************************************************************)
subsection ‹Faking messages›
(******************************************************************************)

text ‹Channel messages that are fakeable from a given set of channel
messages.  Parameters are a set of atoms and a set of freshness identifiers.

For faking messages on dynamic non-authentic channels, we cannot allow the
intruder to use arbitrary keys. Otherwise, we would lose the possibility to 
generate fresh values in our model. Therefore, the chosen keys must correspond
to session keys associated with existing runs (i.e., from set 
@{term "rkeys U"}).
›

abbreviation 
  rkeys :: "fid_t set  key set" where
  "rkeys U  sesK`(λ(x, y). x $ y)`(U × (UNIV::nat set))"

lemma rkeys_sesK [simp, dest]: "sesK (R$i)  rkeys U  R  U"
by (auto simp add: image_def)


inductive_set 
  fake :: "atom set  fid_t set  chmsg set  chmsg set"
  for T :: "atom set"
  and U :: "fid_t set"
  and H :: "chmsg set"
where 
  fake_Inj:
    "M  H  M  fake T U H"
| fake_StatCh: 
    " set M  extr T H; auth  c  A  bad  B  bad   
    StatCh c A B (Msg M)  fake T U H"
| fake_DynCh:  
    " set M  extr T H; auth  c  K  rkeys U  aKey K  extr T H  
    DynCh c K (Msg M)  fake T U H"

declare fake.cases [elim]
declare fake.intros [intro]

lemmas fake_intros = fake_StatCh fake_DynCh

lemma fake_expanding [intro]: "H  fake T U H"
by (auto)

lemma fake_monotone [intro]: "G  H  fake T U G  fake T U H"
by (safe, erule fake.cases, auto intro!: fake_intros)

lemma fake_monotone_param1 [intro]: 
  "T  T'  fake T U H  fake T' U H" 
by (safe, erule fake.cases, auto intro!: fake_intros)

lemmas fake_mono [elim] = fake_monotone [THEN [2] rev_subsetD]
lemmas fake_mono_param1 [elim] = fake_monotone_param1 [THEN [2] rev_subsetD]


subsubsection ‹Atoms and extr together with fake›
(******************************************************************************)

lemma atoms_fake [simp]: "atoms (fake T U H) = T  atoms H"
proof -
  {
    fix At 
    assume "At  T"
    hence "At  atoms (fake T U H)"
    proof -
      {
        fix A B 
        have "Insec A B (Msg [At])  fake T U H" using At  T
        by (intro fake_StatCh) (auto)
      }
      thus ?thesis by (intro at_StatCh) (auto)
    qed
  }
  moreover
  {
    fix At
    assume "At  atoms (fake T U H) "
    hence "At  T  atoms H" by cases blast+
  }
  ultimately show ?thesis by auto
qed


lemma extr_fake [simp]: 
  assumes "T'  T" shows "extr T (fake T' U H) = extr T H"
proof (intro equalityI subsetI) 
  fix At
  assume "At  extr T (fake T' U H)"
  with assms have "At  extr T (fake T U H)" by auto
  thus "At  extr T H" by induct auto
qed auto

(*
lemma extr_fake [simp]: "extr T (fake T U H) = extr T H"
proof -
  {
    fix At
    assume "At ∈ extr T (fake T U H)"
    hence "At ∈ extr T H" by induct auto
  }
  thus ?thesis by auto
qed
*)

end