src/HOL/Auth/OtwayRees_Bad.ML
changeset 5114 c729d4c299c1
parent 5076 fbc9d95b62ba
child 5223 4cb05273f764
equal deleted inserted replaced
5113:c4da11bb0592 5114:c729d4c299c1
    25 AddDs [impOfSubs Fake_parts_insert];
    25 AddDs [impOfSubs Fake_parts_insert];
    26 
    26 
    27 
    27 
    28 (*A "possibility property": there are traces that reach the end*)
    28 (*A "possibility property": there are traces that reach the end*)
    29 Goal 
    29 Goal 
    30  "!!A B. [| A ~= B; A ~= Server; B ~= Server |]   \
    30  "[| A ~= B; A ~= Server; B ~= Server |]   \
    31 \        ==> EX K. EX NA. EX evs: otway.          \
    31 \  ==> EX K. EX NA. EX evs: otway.          \
    32 \               Says B A {|Nonce NA, Crypt (shrK A) {|Nonce NA, Key K|}|} \
    32 \         Says B A {|Nonce NA, Crypt (shrK A) {|Nonce NA, Key K|}|} \
    33 \                 : set evs";
    33 \           : set evs";
    34 by (REPEAT (resolve_tac [exI,bexI] 1));
    34 by (REPEAT (resolve_tac [exI,bexI] 1));
    35 by (rtac (otway.Nil RS otway.OR1 RS otway.OR2 RS otway.OR3 RS otway.OR4) 2);
    35 by (rtac (otway.Nil RS otway.OR1 RS otway.OR2 RS otway.OR3 RS otway.OR4) 2);
    36 by possibility_tac;
    36 by possibility_tac;
    37 result();
    37 result();
    38 
    38 
    39 
    39 
    40 (**** Inductive proofs about otway ****)
    40 (**** Inductive proofs about otway ****)
    41 
    41 
    42 (*Nobody sends themselves messages*)
    42 (*Nobody sends themselves messages*)
    43 Goal "!!evs. evs : otway ==> ALL A X. Says A A X ~: set evs";
    43 Goal "evs : otway ==> ALL A X. Says A A X ~: set evs";
    44 by (etac otway.induct 1);
    44 by (etac otway.induct 1);
    45 by Auto_tac;
    45 by Auto_tac;
    46 qed_spec_mp "not_Says_to_self";
    46 qed_spec_mp "not_Says_to_self";
    47 Addsimps [not_Says_to_self];
    47 Addsimps [not_Says_to_self];
    48 AddSEs   [not_Says_to_self RSN (2, rev_notE)];
    48 AddSEs   [not_Says_to_self RSN (2, rev_notE)];
    49 
    49 
    50 
    50 
    51 (** For reasoning about the encrypted portion of messages **)
    51 (** For reasoning about the encrypted portion of messages **)
    52 
    52 
    53 Goal "!!evs. Says A' B {|N, Agent A, Agent B, X|} : set evs \
    53 Goal "Says A' B {|N, Agent A, Agent B, X|} : set evs \
    54 \                ==> X : analz (spies evs)";
    54 \          ==> X : analz (spies evs)";
    55 by (dtac (Says_imp_spies RS analz.Inj) 1);
    55 by (dtac (Says_imp_spies RS analz.Inj) 1);
    56 by (Blast_tac 1);
    56 by (Blast_tac 1);
    57 qed "OR2_analz_spies";
    57 qed "OR2_analz_spies";
    58 
    58 
    59 Goal "!!evs. Says S' B {|N, X, Crypt (shrK B) X'|} : set evs \
    59 Goal "Says S' B {|N, X, Crypt (shrK B) X'|} : set evs \
    60 \                ==> X : analz (spies evs)";
    60 \          ==> X : analz (spies evs)";
    61 by (dtac (Says_imp_spies RS analz.Inj) 1);
    61 by (dtac (Says_imp_spies RS analz.Inj) 1);
    62 by (Blast_tac 1);
    62 by (Blast_tac 1);
    63 qed "OR4_analz_spies";
    63 qed "OR4_analz_spies";
    64 
    64 
    65 Goal "!!evs. Says Server B {|NA, X, Crypt K' {|NB,K|}|} : set evs \
    65 Goal "Says Server B {|NA, X, Crypt K' {|NB,K|}|} : set evs \
    66 \                ==> K : parts (spies evs)";
    66 \          ==> K : parts (spies evs)";
    67 by (Blast_tac 1);
    67 by (Blast_tac 1);
    68 qed "Oops_parts_spies";
    68 qed "Oops_parts_spies";
    69 
    69 
    70 bind_thm ("OR2_parts_spies",
    70 bind_thm ("OR2_parts_spies",
    71           OR2_analz_spies RS (impOfSubs analz_subset_parts));
    71           OR2_analz_spies RS (impOfSubs analz_subset_parts));
    83 
    83 
    84 (** Theorems of the form X ~: parts (spies evs) imply that NOBODY
    84 (** Theorems of the form X ~: parts (spies evs) imply that NOBODY
    85     sends messages containing X! **)
    85     sends messages containing X! **)
    86 
    86 
    87 (*Spy never sees a good agent's shared key!*)
    87 (*Spy never sees a good agent's shared key!*)
    88 Goal 
    88 Goal "evs : otway ==> (Key (shrK A) : parts (spies evs)) = (A : bad)";
    89  "!!evs. evs : otway ==> (Key (shrK A) : parts (spies evs)) = (A : bad)";
       
    90 by (parts_induct_tac 1);
    89 by (parts_induct_tac 1);
    91 by (ALLGOALS Blast_tac);
    90 by (ALLGOALS Blast_tac);
    92 qed "Spy_see_shrK";
    91 qed "Spy_see_shrK";
    93 Addsimps [Spy_see_shrK];
    92 Addsimps [Spy_see_shrK];
    94 
    93 
    95 Goal 
    94 Goal "evs : otway ==> (Key (shrK A) : analz (spies evs)) = (A : bad)";
    96  "!!evs. evs : otway ==> (Key (shrK A) : analz (spies evs)) = (A : bad)";
       
    97 by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset()));
    95 by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset()));
    98 qed "Spy_analz_shrK";
    96 qed "Spy_analz_shrK";
    99 Addsimps [Spy_analz_shrK];
    97 Addsimps [Spy_analz_shrK];
   100 
    98 
   101 AddSDs [Spy_see_shrK RSN (2, rev_iffD1), 
    99 AddSDs [Spy_see_shrK RSN (2, rev_iffD1), 
   102 	Spy_analz_shrK RSN (2, rev_iffD1)];
   100 	Spy_analz_shrK RSN (2, rev_iffD1)];
   103 
   101 
   104 
   102 
   105 (*Nobody can have used non-existent keys!*)
   103 (*Nobody can have used non-existent keys!*)
   106 Goal "!!evs. evs : otway ==>          \
   104 Goal "evs : otway ==> Key K ~: used evs --> K ~: keysFor (parts (spies evs))";
   107 \         Key K ~: used evs --> K ~: keysFor (parts (spies evs))";
       
   108 by (parts_induct_tac 1);
   105 by (parts_induct_tac 1);
   109 (*Fake*)
   106 (*Fake*)
   110 by (blast_tac (claset() addSDs [keysFor_parts_insert]) 1);
   107 by (blast_tac (claset() addSDs [keysFor_parts_insert]) 1);
   111 (*OR2, OR3*)
   108 (*OR2, OR3*)
   112 by (ALLGOALS Blast_tac);
   109 by (ALLGOALS Blast_tac);
   122 
   119 
   123 (*** Proofs involving analz ***)
   120 (*** Proofs involving analz ***)
   124 
   121 
   125 (*Describes the form of K and NA when the Server sends this message.  Also
   122 (*Describes the form of K and NA when the Server sends this message.  Also
   126   for Oops case.*)
   123   for Oops case.*)
   127 Goal 
   124 Goal "[| Says Server B {|NA, X, Crypt (shrK B) {|NB, Key K|}|} : set evs; \
   128  "!!evs. [| Says Server B {|NA, X, Crypt (shrK B) {|NB, Key K|}|} : set evs; \
   125 \        evs : otway |]                                           \
   129 \           evs : otway |]                                           \
   126 \  ==> K ~: range shrK & (EX i. NA = Nonce i) & (EX j. NB = Nonce j)";
   130 \     ==> K ~: range shrK & (EX i. NA = Nonce i) & (EX j. NB = Nonce j)";
       
   131 by (etac rev_mp 1);
   127 by (etac rev_mp 1);
   132 by (etac otway.induct 1);
   128 by (etac otway.induct 1);
   133 by (ALLGOALS Simp_tac);
   129 by (ALLGOALS Simp_tac);
   134 by (ALLGOALS Blast_tac);
   130 by (ALLGOALS Blast_tac);
   135 qed "Says_Server_message_form";
   131 qed "Says_Server_message_form";
   154 
   150 
   155 
   151 
   156 (** Session keys are not used to encrypt other session keys **)
   152 (** Session keys are not used to encrypt other session keys **)
   157 
   153 
   158 (*The equality makes the induction hypothesis easier to apply*)
   154 (*The equality makes the induction hypothesis easier to apply*)
   159 Goal  
   155 Goal "evs : otway ==>                                 \
   160  "!!evs. evs : otway ==>                                    \
   156 \  ALL K KK. KK <= Compl (range shrK) -->             \
   161 \  ALL K KK. KK <= Compl (range shrK) -->                   \
   157 \         (Key K : analz (Key``KK Un (spies evs))) =  \
   162 \            (Key K : analz (Key``KK Un (spies evs))) =  \
   158 \         (K : KK | Key K : analz (spies evs))";
   163 \            (K : KK | Key K : analz (spies evs))";
       
   164 by (etac otway.induct 1);
   159 by (etac otway.induct 1);
   165 by analz_spies_tac;
   160 by analz_spies_tac;
   166 by (REPEAT_FIRST (resolve_tac [allI, impI]));
   161 by (REPEAT_FIRST (resolve_tac [allI, impI]));
   167 by (REPEAT_FIRST (rtac analz_image_freshK_lemma ));
   162 by (REPEAT_FIRST (rtac analz_image_freshK_lemma ));
   168 by (ALLGOALS (asm_simp_tac analz_image_freshK_ss));
   163 by (ALLGOALS (asm_simp_tac analz_image_freshK_ss));
   169 (*Fake*) 
   164 (*Fake*) 
   170 by (spy_analz_tac 1);
   165 by (spy_analz_tac 1);
   171 qed_spec_mp "analz_image_freshK";
   166 qed_spec_mp "analz_image_freshK";
   172 
   167 
   173 
   168 
   174 Goal
   169 Goal "[| evs : otway;  KAB ~: range shrK |] ==>       \
   175  "!!evs. [| evs : otway;  KAB ~: range shrK |] ==>          \
   170 \     Key K : analz (insert (Key KAB) (spies evs)) =  \
   176 \        Key K : analz (insert (Key KAB) (spies evs)) =  \
   171 \     (K = KAB | Key K : analz (spies evs))";
   177 \        (K = KAB | Key K : analz (spies evs))";
       
   178 by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
   172 by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
   179 qed "analz_insert_freshK";
   173 qed "analz_insert_freshK";
   180 
   174 
   181 
   175 
   182 (*** The Key K uniquely identifies the Server's  message. **)
   176 (*** The Key K uniquely identifies the Server's  message. **)
   183 
   177 
   184 Goal 
   178 Goal "evs : otway ==>                                                  \
   185  "!!evs. evs : otway ==>                                                  \
   179 \     EX B' NA' NB' X'. ALL B NA NB X.                                    \
   186 \   EX B' NA' NB' X'. ALL B NA NB X.                                      \
       
   187 \     Says Server B {|NA, X, Crypt (shrK B) {|NB, K|}|} : set evs -->     \
   180 \     Says Server B {|NA, X, Crypt (shrK B) {|NB, K|}|} : set evs -->     \
   188 \     B=B' & NA=NA' & NB=NB' & X=X'";
   181 \     B=B' & NA=NA' & NB=NB' & X=X'";
   189 by (etac otway.induct 1);
   182 by (etac otway.induct 1);
   190 by (ALLGOALS (asm_simp_tac (simpset() addsimps [all_conj_distrib])));
   183 by (ALLGOALS (asm_simp_tac (simpset() addsimps [all_conj_distrib])));
   191 by (ALLGOALS Clarify_tac);
   184 by (ALLGOALS Clarify_tac);
   196 by (REPEAT (ares_tac [refl,exI,impI,conjI] 2));
   189 by (REPEAT (ares_tac [refl,exI,impI,conjI] 2));
   197 (*...we assume X is a recent message, and handle this case by contradiction*)
   190 (*...we assume X is a recent message, and handle this case by contradiction*)
   198 by (blast_tac (claset() addSEs spies_partsEs) 1);
   191 by (blast_tac (claset() addSEs spies_partsEs) 1);
   199 val lemma = result();
   192 val lemma = result();
   200 
   193 
   201 Goal 
   194 Goal "[| Says Server B {|NA, X, Crypt (shrK B) {|NB, K|}|}   : set evs; \ 
   202  "!!evs. [| Says Server B {|NA, X, Crypt (shrK B) {|NB, K|}|}   : set evs; \ 
   195 \        Says Server B' {|NA',X',Crypt (shrK B') {|NB',K|}|} : set evs; \
   203 \           Says Server B' {|NA',X',Crypt (shrK B') {|NB',K|}|} : set evs; \
   196 \        evs : otway |] ==> X=X' & B=B' & NA=NA' & NB=NB'";
   204 \           evs : otway |] ==> X=X' & B=B' & NA=NA' & NB=NB'";
       
   205 by (prove_unique_tac lemma 1);
   197 by (prove_unique_tac lemma 1);
   206 qed "unique_session_keys";
   198 qed "unique_session_keys";
   207 
   199 
   208 
   200 
   209 (** Crucial secrecy property: Spy does not see the keys sent in msg OR3
   201 (** Crucial secrecy property: Spy does not see the keys sent in msg OR3
   210     Does not in itself guarantee security: an attack could violate 
   202     Does not in itself guarantee security: an attack could violate 
   211     the premises, e.g. by having A=Spy **)
   203     the premises, e.g. by having A=Spy **)
   212 
   204 
   213 Goal 
   205 Goal "[| A ~: bad;  B ~: bad;  evs : otway |]                      \
   214  "!!evs. [| A ~: bad;  B ~: bad;  evs : otway |]                      \
   206 \     ==> Says Server B                                            \
   215 \        ==> Says Server B                                            \
   207 \           {|NA, Crypt (shrK A) {|NA, Key K|},                    \
   216 \              {|NA, Crypt (shrK A) {|NA, Key K|},                    \
   208 \             Crypt (shrK B) {|NB, Key K|}|} : set evs -->         \
   217 \                Crypt (shrK B) {|NB, Key K|}|} : set evs -->         \
   209 \         Notes Spy {|NA, NB, Key K|} ~: set evs -->               \
   218 \            Notes Spy {|NA, NB, Key K|} ~: set evs -->               \
   210 \         Key K ~: analz (spies evs)";
   219 \            Key K ~: analz (spies evs)";
       
   220 by (etac otway.induct 1);
   211 by (etac otway.induct 1);
   221 by analz_spies_tac;
   212 by analz_spies_tac;
   222 by (ALLGOALS
   213 by (ALLGOALS
   223     (asm_simp_tac (simpset() addcongs [conj_cong] 
   214     (asm_simp_tac (simpset() addcongs [conj_cong] 
   224                              addsimps [analz_insert_eq, analz_insert_freshK]
   215                              addsimps [analz_insert_eq, analz_insert_freshK]
   231 by (Blast_tac 2);
   222 by (Blast_tac 2);
   232 (*Fake*) 
   223 (*Fake*) 
   233 by (spy_analz_tac 1);
   224 by (spy_analz_tac 1);
   234 val lemma = result() RS mp RS mp RSN(2,rev_notE);
   225 val lemma = result() RS mp RS mp RSN(2,rev_notE);
   235 
   226 
   236 Goal 
   227 Goal "[| Says Server B                                           \
   237  "!!evs. [| Says Server B                                           \
   228 \         {|NA, Crypt (shrK A) {|NA, Key K|},                    \
   238 \            {|NA, Crypt (shrK A) {|NA, Key K|},                    \
   229 \               Crypt (shrK B) {|NB, Key K|}|} : set evs;        \
   239 \                  Crypt (shrK B) {|NB, Key K|}|} : set evs;        \
   230 \        Notes Spy {|NA, NB, Key K|} ~: set evs;                 \
   240 \           Notes Spy {|NA, NB, Key K|} ~: set evs;                 \
   231 \        A ~: bad;  B ~: bad;  evs : otway |]                    \
   241 \           A ~: bad;  B ~: bad;  evs : otway |]                    \
   232 \     ==> Key K ~: analz (spies evs)";
   242 \        ==> Key K ~: analz (spies evs)";
       
   243 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1);
   233 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1);
   244 by (blast_tac (claset() addSEs [lemma]) 1);
   234 by (blast_tac (claset() addSEs [lemma]) 1);
   245 qed "Spy_not_see_encrypted_key";
   235 qed "Spy_not_see_encrypted_key";
   246 
   236 
   247 
   237 
   249 
   239 
   250 (*Only OR1 can have caused such a part of a message to appear.
   240 (*Only OR1 can have caused such a part of a message to appear.
   251   I'm not sure why A ~= B premise is needed: OtwayRees.ML doesn't need it.
   241   I'm not sure why A ~= B premise is needed: OtwayRees.ML doesn't need it.
   252   Perhaps it's because OR2 has two similar-looking encrypted messages in
   242   Perhaps it's because OR2 has two similar-looking encrypted messages in
   253         this version.*)
   243         this version.*)
   254 Goal 
   244 Goal "[| A ~: bad;  A ~= B;  evs : otway |]                \
   255  "!!evs. [| A ~: bad;  A ~= B;  evs : otway |]                \
   245 \     ==> Crypt (shrK A) {|NA, Agent A, Agent B|} : parts (spies evs) --> \
   256 \        ==> Crypt (shrK A) {|NA, Agent A, Agent B|} : parts (spies evs) --> \
   246 \         Says A B {|NA, Agent A, Agent B,                  \
   257 \            Says A B {|NA, Agent A, Agent B,                  \
   247 \                    Crypt (shrK A) {|NA, Agent A, Agent B|}|}  : set evs";
   258 \                       Crypt (shrK A) {|NA, Agent A, Agent B|}|}  : set evs";
       
   259 by (parts_induct_tac 1);
   248 by (parts_induct_tac 1);
   260 by (ALLGOALS Blast_tac);
   249 by (ALLGOALS Blast_tac);
   261 qed_spec_mp "Crypt_imp_OR1";
   250 qed_spec_mp "Crypt_imp_OR1";
   262 
   251 
   263 
   252 
   264 (*Crucial property: If the encrypted message appears, and A has used NA
   253 (*Crucial property: If the encrypted message appears, and A has used NA
   265   to start a run, then it originated with the Server!*)
   254   to start a run, then it originated with the Server!*)
   266 (*Only it is FALSE.  Somebody could make a fake message to Server
   255 (*Only it is FALSE.  Somebody could make a fake message to Server
   267           substituting some other nonce NA' for NB.*)
   256           substituting some other nonce NA' for NB.*)
   268 Goal 
   257 Goal "[| A ~: bad;  evs : otway |]                                \
   269  "!!evs. [| A ~: bad;  evs : otway |]                                \
   258 \     ==> Crypt (shrK A) {|NA, Key K|} : parts (spies evs) -->    \
   270 \        ==> Crypt (shrK A) {|NA, Key K|} : parts (spies evs) -->    \
   259 \         Says A B {|NA, Agent A, Agent B,                        \
   271 \            Says A B {|NA, Agent A, Agent B,                        \
   260 \                    Crypt (shrK A) {|NA, Agent A, Agent B|}|}    \
   272 \                       Crypt (shrK A) {|NA, Agent A, Agent B|}|}    \
   261 \          : set evs -->                                          \
   273 \             : set evs -->                                          \
   262 \         (EX B NB. Says Server B                                 \
   274 \            (EX B NB. Says Server B                                 \
   263 \              {|NA,                                              \
   275 \                 {|NA,                                              \
   264 \                Crypt (shrK A) {|NA, Key K|},                    \
   276 \                   Crypt (shrK A) {|NA, Key K|},                    \
   265 \                Crypt (shrK B) {|NB, Key K|}|}  : set evs)";
   277 \                   Crypt (shrK B) {|NB, Key K|}|}  : set evs)";
       
   278 by (parts_induct_tac 1);
   266 by (parts_induct_tac 1);
   279 (*Fake*)
   267 (*Fake*)
   280 by (Blast_tac 1);
   268 by (Blast_tac 1);
   281 (*OR1: it cannot be a new Nonce, contradiction.*)
   269 (*OR1: it cannot be a new Nonce, contradiction.*)
   282 by (Blast_tac 1);
   270 by (Blast_tac 1);