src/HOL/Auth/OtwayRees_AN.ML
changeset 6308 76f3865a2b1d
parent 5535 678999604ee9
child 6915 4ab8e31a8421
equal deleted inserted replaced
6307:fdf236c98914 6308:76f3865a2b1d
    10 From page 11 of
    10 From page 11 of
    11   Abadi and Needham.  Prudent Engineering Practice for Cryptographic Protocols.
    11   Abadi and Needham.  Prudent Engineering Practice for Cryptographic Protocols.
    12   IEEE Trans. SE 22 (1), 1996
    12   IEEE Trans. SE 22 (1), 1996
    13 *)
    13 *)
    14 
    14 
    15 AddEs spies_partsEs;
    15 AddEs knows_Spy_partsEs;
    16 AddDs [impOfSubs analz_subset_parts];
    16 AddDs [impOfSubs analz_subset_parts];
    17 AddDs [impOfSubs Fake_parts_insert];
    17 AddDs [impOfSubs Fake_parts_insert];
    18 
    18 
    19 
    19 
    20 (*A "possibility property": there are traces that reach the end*)
    20 (*A "possibility property": there are traces that reach the end*)
    21 Goal "[| B ~= Server |]   \
    21 Goal "[| B ~= Server |]   \
    22 \     ==> EX K. EX NA. EX evs: otway.                                      \
    22 \     ==> EX K. EX NA. EX evs: otway.                                      \
    23 \          Says B A (Crypt (shrK A) {|Nonce NA, Agent A, Agent B, Key K|}) \
    23 \          Says B A (Crypt (shrK A) {|Nonce NA, Agent A, Agent B, Key K|}) \
    24 \            : set evs";
    24 \            : set evs";
    25 by (REPEAT (resolve_tac [exI,bexI] 1));
    25 by (REPEAT (resolve_tac [exI,bexI] 1));
    26 by (rtac (otway.Nil RS otway.OR1 RS otway.OR2 RS otway.OR3 RS otway.OR4) 2);
    26 by (rtac (otway.Nil RS 
       
    27           otway.OR1 RS otway.Reception RS
       
    28           otway.OR2 RS otway.Reception RS 
       
    29           otway.OR3 RS otway.Reception RS otway.OR4) 2);
    27 by possibility_tac;
    30 by possibility_tac;
    28 result();
    31 result();
    29 
    32 
       
    33 Goal "[| Gets B X : set evs; evs : otway |] ==> EX A. Says A B X : set evs";
       
    34 by (etac rev_mp 1);
       
    35 by (etac otway.induct 1);
       
    36 by Auto_tac;
       
    37 qed"Gets_imp_Says";
       
    38 
       
    39 (*Must be proved separately for each protocol*)
       
    40 Goal "[| Gets B X : set evs; evs : otway |]  ==> X : knows Spy evs";
       
    41 by (blast_tac (claset() addSDs [Gets_imp_Says, Says_imp_knows_Spy]) 1);
       
    42 qed"Gets_imp_knows_Spy";
       
    43 AddDs [Gets_imp_knows_Spy RS parts.Inj];
       
    44 
    30 
    45 
    31 (**** Inductive proofs about otway ****)
    46 (**** Inductive proofs about otway ****)
    32 
    47 
    33 (** For reasoning about the encrypted portion of messages **)
    48 (** For reasoning about the encrypted portion of messages **)
    34 
    49 
    35 Goal "Says S' B {|X, Crypt(shrK B) X'|} : set evs ==> \
    50 Goal "[| Gets B {|X, Crypt(shrK B) X'|} : set evs;  evs : otway |] ==> \
    36 \          X : analz (spies evs)";
    51 \          X : analz (knows Spy evs)";
    37 by (dtac (Says_imp_spies RS analz.Inj) 1);
    52 by (blast_tac (claset() addSDs [Gets_imp_knows_Spy RS analz.Inj]) 1);
    38 by (Blast_tac 1);
    53 qed "OR4_analz_knows_Spy";
    39 qed "OR4_analz_spies";
    54 
    40 
    55 Goal "Says Server B {|X, Crypt K' {|NB, a, Agent B, K|}|} : set evs \
    41 Goal "Says Server B {|X, Crypt K' {|NB, a, Agent B, K|}|} \
    56 \     ==> K : parts (knows Spy evs)";
    42 \            : set evs ==> K : parts (spies evs)";
    57 by (Blast_tac 1);
    43 by (Blast_tac 1);
    58 qed "Oops_parts_knows_Spy";
    44 qed "Oops_parts_spies";
    59 
    45 
    60 bind_thm ("OR4_parts_knows_Spy",
    46 bind_thm ("OR4_parts_spies",
    61           OR4_analz_knows_Spy RS (impOfSubs analz_subset_parts));
    47           OR4_analz_spies RS (impOfSubs analz_subset_parts));
    62 
    48 
    63 (*For proving the easier theorems about X ~: parts (knows Spy evs).*)
    49 (*For proving the easier theorems about X ~: parts (spies evs).*)
       
    50 fun parts_induct_tac i = 
    64 fun parts_induct_tac i = 
    51     etac otway.induct i			THEN 
    65     etac otway.induct i			THEN 
    52     forward_tac [Oops_parts_spies] (i+6) THEN
    66     forward_tac [Oops_parts_knows_Spy] (i+7) THEN
    53     forward_tac [OR4_parts_spies]  (i+5) THEN
    67     forward_tac [OR4_parts_knows_Spy]  (i+6) THEN
    54     prove_simple_subgoals_tac  i;
    68     prove_simple_subgoals_tac  i;
    55 
    69 
    56 
    70 
    57 (** Theorems of the form X ~: parts (spies evs) imply that NOBODY
    71 (** Theorems of the form X ~: parts (knows Spy evs) imply that NOBODY
    58     sends messages containing X! **)
    72     sends messages containing X! **)
    59 
    73 
    60 (*Spy never sees a good agent's shared key!*)
    74 (*Spy never sees a good agent's shared key!*)
    61 Goal "evs : otway ==> (Key (shrK A) : parts (spies evs)) = (A : bad)";
    75 Goal "evs : otway ==> (Key (shrK A) : parts (knows Spy evs)) = (A : bad)";
    62 by (parts_induct_tac 1);
    76 by (parts_induct_tac 1);
    63 by (ALLGOALS Blast_tac);
    77 by (ALLGOALS Blast_tac);
    64 qed "Spy_see_shrK";
    78 qed "Spy_see_shrK";
    65 Addsimps [Spy_see_shrK];
    79 Addsimps [Spy_see_shrK];
    66 
    80 
    67 Goal "evs : otway ==> (Key (shrK A) : analz (spies evs)) = (A : bad)";
    81 Goal "evs : otway ==> (Key (shrK A) : analz (knows Spy evs)) = (A : bad)";
    68 by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset()));
    82 by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset()));
    69 qed "Spy_analz_shrK";
    83 qed "Spy_analz_shrK";
    70 Addsimps [Spy_analz_shrK];
    84 Addsimps [Spy_analz_shrK];
    71 
    85 
    72 AddSDs [Spy_see_shrK RSN (2, rev_iffD1), 
    86 AddSDs [Spy_see_shrK RSN (2, rev_iffD1), 
    73 	Spy_analz_shrK RSN (2, rev_iffD1)];
    87 	Spy_analz_shrK RSN (2, rev_iffD1)];
    74 
    88 
    75 
    89 
    76 (*Nobody can have used non-existent keys!*)
    90 (*Nobody can have used non-existent keys!*)
    77 Goal "evs : otway ==> Key K ~: used evs --> K ~: keysFor (parts (spies evs))";
    91 Goal "evs : otway ==> Key K ~: used evs --> K ~: keysFor (parts (knows Spy evs))";
    78 by (parts_induct_tac 1);
    92 by (parts_induct_tac 1);
    79 (*Fake*)
    93 (*Fake*)
    80 by (blast_tac (claset() addSDs [keysFor_parts_insert]) 1);
    94 by (blast_tac (claset() addSDs [keysFor_parts_insert]) 1);
    81 (*OR3*)
    95 (*OR3*)
    82 by (Blast_tac 1);
    96 by (Blast_tac 1);
   105 by (Blast_tac 1);
   119 by (Blast_tac 1);
   106 qed "Says_Server_message_form";
   120 qed "Says_Server_message_form";
   107 
   121 
   108 
   122 
   109 (*For proofs involving analz.*)
   123 (*For proofs involving analz.*)
   110 val analz_spies_tac = 
   124 val analz_knows_Spy_tac = 
   111     dtac OR4_analz_spies 6 THEN
   125     dtac OR4_analz_knows_Spy 7 THEN assume_tac 7 THEN
   112     forward_tac [Says_Server_message_form] 7 THEN
   126     forward_tac [Says_Server_message_form] 8 THEN assume_tac 8 THEN
   113     assume_tac 7 THEN
   127     REPEAT ((eresolve_tac [exE, conjE] ORELSE' hyp_subst_tac) 8);
   114     REPEAT ((eresolve_tac [exE, conjE] ORELSE' hyp_subst_tac) 7);
       
   115 
   128 
   116 
   129 
   117 (****
   130 (****
   118  The following is to prove theorems of the form
   131  The following is to prove theorems of the form
   119 
   132 
   120   Key K : analz (insert (Key KAB) (spies evs)) ==>
   133   Key K : analz (insert (Key KAB) (knows Spy evs)) ==>
   121   Key K : analz (spies evs)
   134   Key K : analz (knows Spy evs)
   122 
   135 
   123  A more general formula must be proved inductively.
   136  A more general formula must be proved inductively.
   124 ****)
   137 ****)
   125 
   138 
   126 
   139 
   127 (** Session keys are not used to encrypt other session keys **)
   140 (** Session keys are not used to encrypt other session keys **)
   128 
   141 
   129 (*The equality makes the induction hypothesis easier to apply*)
   142 (*The equality makes the induction hypothesis easier to apply*)
   130 Goal "evs : otway ==>                                 \
   143 Goal "evs : otway ==>                                 \
   131 \  ALL K KK. KK <= -(range shrK) -->                  \
   144 \  ALL K KK. KK <= -(range shrK) -->                  \
   132 \         (Key K : analz (Key``KK Un (spies evs))) =  \
   145 \         (Key K : analz (Key``KK Un (knows Spy evs))) =  \
   133 \         (K : KK | Key K : analz (spies evs))";
   146 \         (K : KK | Key K : analz (knows Spy evs))";
   134 by (etac otway.induct 1);
   147 by (etac otway.induct 1);
   135 by analz_spies_tac;
   148 by analz_knows_Spy_tac;
   136 by (REPEAT_FIRST (resolve_tac [allI, impI]));
   149 by (REPEAT_FIRST (resolve_tac [allI, impI]));
   137 by (REPEAT_FIRST (rtac analz_image_freshK_lemma ));
   150 by (REPEAT_FIRST (rtac analz_image_freshK_lemma ));
   138 by (ALLGOALS (asm_simp_tac analz_image_freshK_ss));
   151 by (ALLGOALS (asm_simp_tac analz_image_freshK_ss));
   139 (*Fake*) 
   152 (*Fake*) 
   140 by (spy_analz_tac 1);
   153 by (spy_analz_tac 1);
   141 qed_spec_mp "analz_image_freshK";
   154 qed_spec_mp "analz_image_freshK";
   142 
   155 
   143 
   156 
   144 Goal "[| evs : otway;  KAB ~: range shrK |] ==>       \
   157 Goal "[| evs : otway;  KAB ~: range shrK |] ==>       \
   145 \     Key K : analz (insert (Key KAB) (spies evs)) =  \
   158 \     Key K : analz (insert (Key KAB) (knows Spy evs)) =  \
   146 \     (K = KAB | Key K : analz (spies evs))";
   159 \     (K = KAB | Key K : analz (knows Spy evs))";
   147 by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
   160 by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
   148 qed "analz_insert_freshK";
   161 qed "analz_insert_freshK";
   149 
   162 
   150 
   163 
   151 (*** The Key K uniquely identifies the Server's message. **)
   164 (*** The Key K uniquely identifies the Server's message. **)
   163 by (ex_strip_tac 2);
   176 by (ex_strip_tac 2);
   164 by (Blast_tac 2);
   177 by (Blast_tac 2);
   165 by (expand_case_tac "K = ?y" 1);
   178 by (expand_case_tac "K = ?y" 1);
   166 by (REPEAT (ares_tac [refl,exI,impI,conjI] 2));
   179 by (REPEAT (ares_tac [refl,exI,impI,conjI] 2));
   167 (*...we assume X is a recent message and handle this case by contradiction*)
   180 (*...we assume X is a recent message and handle this case by contradiction*)
   168 by (blast_tac (claset() addSEs spies_partsEs) 1);
   181 by (blast_tac (claset() addSEs knows_Spy_partsEs) 1);
   169 val lemma = result();
   182 val lemma = result();
   170 
   183 
   171 
   184 
   172 Goal "[| Says Server B                                           \
   185 Goal "[| Says Server B                                           \
   173 \         {|Crypt (shrK A) {|NA, Agent A, Agent B, K|},         \
   186 \         {|Crypt (shrK A) {|NA, Agent A, Agent B, K|},         \
   186 
   199 
   187 (**** Authenticity properties relating to NA ****)
   200 (**** Authenticity properties relating to NA ****)
   188 
   201 
   189 (*If the encrypted message appears then it originated with the Server!*)
   202 (*If the encrypted message appears then it originated with the Server!*)
   190 Goal "[| A ~: bad;  A ~= B;  evs : otway |]                 \
   203 Goal "[| A ~: bad;  A ~= B;  evs : otway |]                 \
   191 \     ==> Crypt (shrK A) {|NA, Agent A, Agent B, Key K|} : parts (spies evs) \
   204 \     ==> Crypt (shrK A) {|NA, Agent A, Agent B, Key K|} : parts (knows Spy evs) \
   192 \      --> (EX NB. Says Server B                                          \
   205 \      --> (EX NB. Says Server B                                          \
   193 \                   {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   206 \                   {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   194 \                     Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   207 \                     Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   195 \                   : set evs)";
   208 \                   : set evs)";
   196 by (parts_induct_tac 1);
   209 by (parts_induct_tac 1);
   201 qed_spec_mp "NA_Crypt_imp_Server_msg";
   214 qed_spec_mp "NA_Crypt_imp_Server_msg";
   202 
   215 
   203 
   216 
   204 (*Corollary: if A receives B's OR4 message then it originated with the Server.
   217 (*Corollary: if A receives B's OR4 message then it originated with the Server.
   205   Freshness may be inferred from nonce NA.*)
   218   Freshness may be inferred from nonce NA.*)
   206 Goal "[| Says B' A (Crypt (shrK A) {|NA, Agent A, Agent B, Key K|})  \
   219 Goal "[| Gets A (Crypt (shrK A) {|NA, Agent A, Agent B, Key K|})  \
   207 \         : set evs;                                                 \
   220 \         : set evs;                                                 \
   208 \        A ~: bad;  A ~= B;  evs : otway |]                          \
   221 \        A ~: bad;  A ~= B;  evs : otway |]                          \
   209 \     ==> EX NB. Says Server B                                       \
   222 \     ==> EX NB. Says Server B                                       \
   210 \                 {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},  \
   223 \                 {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},  \
   211 \                   Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   224 \                   Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   222 \     ==> Says Server B                                         \
   235 \     ==> Says Server B                                         \
   223 \          {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   236 \          {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   224 \            Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   237 \            Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   225 \         : set evs -->                                         \
   238 \         : set evs -->                                         \
   226 \         Notes Spy {|NA, NB, Key K|} ~: set evs -->            \
   239 \         Notes Spy {|NA, NB, Key K|} ~: set evs -->            \
   227 \         Key K ~: analz (spies evs)";
   240 \         Key K ~: analz (knows Spy evs)";
   228 by (etac otway.induct 1);
   241 by (etac otway.induct 1);
   229 by analz_spies_tac;
   242 by analz_knows_Spy_tac;
   230 by (ALLGOALS
   243 by (ALLGOALS
   231     (asm_simp_tac (simpset() addcongs [conj_cong, if_weak_cong] 
   244     (asm_simp_tac (simpset() addcongs [conj_cong, if_weak_cong] 
   232                              addsimps [analz_insert_eq, analz_insert_freshK]
   245                              addsimps [analz_insert_eq, analz_insert_freshK]
   233                                       @ pushes @ split_ifs)));
   246                                       @ pushes @ split_ifs)));
   234 (*Oops*)
   247 (*Oops*)
   245 \           {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   258 \           {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   246 \             Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   259 \             Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   247 \          : set evs;                                            \
   260 \          : set evs;                                            \
   248 \        Notes Spy {|NA, NB, Key K|} ~: set evs;                 \
   261 \        Notes Spy {|NA, NB, Key K|} ~: set evs;                 \
   249 \        A ~: bad;  B ~: bad;  evs : otway |]                    \
   262 \        A ~: bad;  B ~: bad;  evs : otway |]                    \
   250 \     ==> Key K ~: analz (spies evs)";
   263 \     ==> Key K ~: analz (knows Spy evs)";
   251 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1);
   264 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1);
   252 by (blast_tac (claset() addSEs [lemma]) 1);
   265 by (blast_tac (claset() addSEs [lemma]) 1);
   253 qed "Spy_not_see_encrypted_key";
   266 qed "Spy_not_see_encrypted_key";
   254 
   267 
   255 
   268 
   256 (*A's guarantee.  The Oops premise quantifies over NB because A cannot know
   269 (*A's guarantee.  The Oops premise quantifies over NB because A cannot know
   257   what it is.*)
   270   what it is.*)
   258 Goal "[| Says B' A (Crypt (shrK A) {|NA, Agent A, Agent B, Key K|})  \
   271 Goal "[| Gets A (Crypt (shrK A) {|NA, Agent A, Agent B, Key K|})  \
   259 \         : set evs;                                                 \
   272 \         : set evs;                                                 \
   260 \        ALL NB. Notes Spy {|NA, NB, Key K|} ~: set evs;             \
   273 \        ALL NB. Notes Spy {|NA, NB, Key K|} ~: set evs;             \
   261 \        A ~: bad;  B ~: bad;  A ~= B;  evs : otway |]               \
   274 \        A ~: bad;  B ~: bad;  A ~= B;  evs : otway |]               \
   262 \     ==> Key K ~: analz (spies evs)";
   275 \     ==> Key K ~: analz (knows Spy evs)";
   263 by (blast_tac (claset() addSDs [A_trusts_OR4, Spy_not_see_encrypted_key]) 1);
   276 by (blast_tac (claset() addSDs [A_trusts_OR4, Spy_not_see_encrypted_key]) 1);
   264 qed "A_gets_good_key";
   277 qed "A_gets_good_key";
   265 
   278 
   266 
   279 
   267 (**** Authenticity properties relating to NB ****)
   280 (**** Authenticity properties relating to NB ****)
   268 
   281 
   269 (*If the encrypted message appears then it originated with the Server!*)
   282 (*If the encrypted message appears then it originated with the Server!*)
   270 Goal "[| B ~: bad;  A ~= B;  evs : otway |]                              \
   283 Goal "[| B ~: bad;  A ~= B;  evs : otway |]                              \
   271 \ ==> Crypt (shrK B) {|NB, Agent A, Agent B, Key K|} : parts (spies evs) \
   284 \ ==> Crypt (shrK B) {|NB, Agent A, Agent B, Key K|} : parts (knows Spy evs) \
   272 \     --> (EX NA. Says Server B                                          \
   285 \     --> (EX NA. Says Server B                                          \
   273 \                  {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   286 \                  {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   274 \                    Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   287 \                    Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   275 \                  : set evs)";
   288 \                  : set evs)";
   276 by (parts_induct_tac 1);
   289 by (parts_induct_tac 1);
   281 qed_spec_mp "NB_Crypt_imp_Server_msg";
   294 qed_spec_mp "NB_Crypt_imp_Server_msg";
   282 
   295 
   283 
   296 
   284 (*Guarantee for B: if it gets a well-formed certificate then the Server
   297 (*Guarantee for B: if it gets a well-formed certificate then the Server
   285   has sent the correct message in round 3.*)
   298   has sent the correct message in round 3.*)
   286 Goal "[| Says S' B {|X, Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   299 Goal "[| Gets B {|X, Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   287 \          : set evs;                                                    \
   300 \          : set evs;                                                    \
   288 \        B ~: bad;  A ~= B;  evs : otway |]                              \
   301 \        B ~: bad;  A ~= B;  evs : otway |]                              \
   289 \     ==> EX NA. Says Server B                                           \
   302 \     ==> EX NA. Says Server B                                           \
   290 \                  {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   303 \                  {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   291 \                    Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   304 \                    Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   293 by (blast_tac (claset() addSIs [NB_Crypt_imp_Server_msg]) 1);
   306 by (blast_tac (claset() addSIs [NB_Crypt_imp_Server_msg]) 1);
   294 qed "B_trusts_OR3";
   307 qed "B_trusts_OR3";
   295 
   308 
   296 
   309 
   297 (*The obvious combination of B_trusts_OR3 with Spy_not_see_encrypted_key*)
   310 (*The obvious combination of B_trusts_OR3 with Spy_not_see_encrypted_key*)
   298 Goal "[| Says S' B {|X, Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   311 Goal "[| Gets B {|X, Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   299 \         : set evs;                                                     \
   312 \         : set evs;                                                     \
   300 \        ALL NA. Notes Spy {|NA, NB, Key K|} ~: set evs;                 \
   313 \        ALL NA. Notes Spy {|NA, NB, Key K|} ~: set evs;                 \
   301 \        A ~: bad;  B ~: bad;  A ~= B;  evs : otway |]                   \
   314 \        A ~: bad;  B ~: bad;  A ~= B;  evs : otway |]                   \
   302 \     ==> Key K ~: analz (spies evs)";
   315 \     ==> Key K ~: analz (knows Spy evs)";
   303 by (blast_tac (claset() addDs [B_trusts_OR3, Spy_not_see_encrypted_key]) 1);
   316 by (blast_tac (claset() addDs [B_trusts_OR3, Spy_not_see_encrypted_key]) 1);
   304 qed "B_gets_good_key";
   317 qed "B_gets_good_key";