src/HOL/Auth/Yahalom.ML
changeset 3450 cd73bc206d87
parent 3444 919de2cb3487
child 3464 315694e22856
equal deleted inserted replaced
3449:6b17f82bbf01 3450:cd73bc206d87
     7 
     7 
     8 From page 257 of
     8 From page 257 of
     9   Burrows, Abadi and Needham.  A Logic of Authentication.
     9   Burrows, Abadi and Needham.  A Logic of Authentication.
    10   Proc. Royal Soc. 426 (1989)
    10   Proc. Royal Soc. 426 (1989)
    11 *)
    11 *)
    12 
       
    13 (*to HOL/simpdata.ML ????????????????*)
       
    14 fun prove nm thm  = qed_goal nm HOL.thy thm (fn _ => [blast_tac HOL_cs 1]);
       
    15 prove "imp_disj_not1" "((P --> Q | R)) = (~Q --> P --> R)";
       
    16 prove "imp_disj_not2" "((P --> Q | R)) = (~R --> P --> Q)";
       
    17 
       
    18 
    12 
    19 open Yahalom;
    13 open Yahalom;
    20 
    14 
    21 proof_timing:=true;
    15 proof_timing:=true;
    22 HOL_quantifiers := false;
    16 HOL_quantifiers := false;
   182 by (etac yahalom.induct 1);
   176 by (etac yahalom.induct 1);
   183 by analz_sees_tac;
   177 by analz_sees_tac;
   184 by (REPEAT_FIRST (resolve_tac [allI, impI]));
   178 by (REPEAT_FIRST (resolve_tac [allI, impI]));
   185 by (REPEAT_FIRST (rtac analz_image_freshK_lemma ));
   179 by (REPEAT_FIRST (rtac analz_image_freshK_lemma ));
   186 by (ALLGOALS (asm_simp_tac analz_image_freshK_ss));
   180 by (ALLGOALS (asm_simp_tac analz_image_freshK_ss));
       
   181 (*Fake*) 
       
   182 by (spy_analz_tac 2);
   187 (*Base*)
   183 (*Base*)
   188 by (Blast_tac 1);
   184 by (Blast_tac 1);
   189 (*YM4, Fake*) 
       
   190 by (REPEAT (spy_analz_tac 1));
       
   191 qed_spec_mp "analz_image_freshK";
   185 qed_spec_mp "analz_image_freshK";
   192 
   186 
   193 goal thy
   187 goal thy
   194  "!!evs. [| evs : yahalom lost;  KAB ~: range shrK |] ==>             \
   188  "!!evs. [| evs : yahalom lost;  KAB ~: range shrK |] ==>             \
   195 \        Key K : analz (insert (Key KAB) (sees lost Spy evs)) = \
   189 \        Key K : analz (insert (Key KAB) (sees lost Spy evs)) = \
   200 
   194 
   201 (*** The Key K uniquely identifies the Server's  message. **)
   195 (*** The Key K uniquely identifies the Server's  message. **)
   202 
   196 
   203 goal thy 
   197 goal thy 
   204  "!!evs. evs : yahalom lost ==>                                     \
   198  "!!evs. evs : yahalom lost ==>                                     \
   205 \      EX A' B' NA' NB' X'. ALL A B NA NB X.                             \
   199 \      EX A' B' na' nb' X'. ALL A B na nb X.                             \
   206 \          Says Server A                                            \
   200 \          Says Server A                                            \
   207 \           {|Crypt (shrK A) {|Agent B, Key K, NA, NB|}, X|}        \
   201 \           {|Crypt (shrK A) {|Agent B, Key K, na, nb|}, X|}        \
   208 \          : set_of_list evs --> A=A' & B=B' & NA=NA' & NB=NB' & X=X'";
   202 \          : set_of_list evs --> A=A' & B=B' & na=na' & nb=nb' & X=X'";
   209 by (etac yahalom.induct 1);
   203 by (etac yahalom.induct 1);
   210 by (ALLGOALS (asm_simp_tac (!simpset addsimps [all_conj_distrib])));
   204 by (ALLGOALS (asm_simp_tac (!simpset addsimps [all_conj_distrib])));
   211 by (Step_tac 1);
   205 by (Step_tac 1);
   212 by (ex_strip_tac 2);
   206 by (ex_strip_tac 2);
   213 by (Blast_tac 2);
   207 by (Blast_tac 2);
   219                       delrules [conjI]    (*no split-up to 4 subgoals*)) 1);
   213                       delrules [conjI]    (*no split-up to 4 subgoals*)) 1);
   220 val lemma = result();
   214 val lemma = result();
   221 
   215 
   222 goal thy 
   216 goal thy 
   223 "!!evs. [| Says Server A                                            \
   217 "!!evs. [| Says Server A                                            \
   224 \           {|Crypt (shrK A) {|Agent B, Key K, NA, NB|}, X|}        \
   218 \           {|Crypt (shrK A) {|Agent B, Key K, na, nb|}, X|}        \
   225 \           : set_of_list evs;                                      \
   219 \           : set_of_list evs;                                      \
   226 \          Says Server A'                                           \
   220 \          Says Server A'                                           \
   227 \           {|Crypt (shrK A') {|Agent B', Key K, NA', NB'|}, X'|}   \
   221 \           {|Crypt (shrK A') {|Agent B', Key K, na', nb'|}, X'|}   \
   228 \           : set_of_list evs;                                      \
   222 \           : set_of_list evs;                                      \
   229 \          evs : yahalom lost |]                                    \
   223 \          evs : yahalom lost |]                                    \
   230 \       ==> A=A' & B=B' & NA=NA' & NB=NB'";
   224 \       ==> A=A' & B=B' & na=na' & nb=nb'";
   231 by (prove_unique_tac lemma 1);
   225 by (prove_unique_tac lemma 1);
   232 qed "unique_session_keys";
   226 qed "unique_session_keys";
   233 
   227 
   234 
   228 
   235 (** Crucial secrecy property: Spy does not see the keys sent in msg YM3 **)
   229 (** Crucial secrecy property: Spy does not see the keys sent in msg YM3 **)
   236 
   230 
   237 goal thy 
   231 goal thy 
   238  "!!evs. [| A ~: lost;  B ~: lost;  evs : yahalom lost |]         \
   232  "!!evs. [| A ~: lost;  B ~: lost;  evs : yahalom lost |]         \
   239 \        ==> Says Server A                                        \
   233 \        ==> Says Server A                                        \
   240 \              {|Crypt (shrK A) {|Agent B, Key K, NA, NB|},       \
   234 \              {|Crypt (shrK A) {|Agent B, Key K, na, nb|},       \
   241 \                Crypt (shrK B) {|Agent A, Key K|}|}              \
   235 \                Crypt (shrK B) {|Agent A, Key K|}|}              \
   242 \             : set_of_list evs -->                               \
   236 \             : set_of_list evs -->                               \
   243 \            Says A Spy {|NA, NB, Key K|} ~: set_of_list evs -->  \
   237 \            Says A Spy {|na, nb, Key K|} ~: set_of_list evs -->  \
   244 \            Key K ~: analz (sees lost Spy evs)";
   238 \            Key K ~: analz (sees lost Spy evs)";
   245 by (etac yahalom.induct 1);
   239 by (etac yahalom.induct 1);
   246 by analz_sees_tac;
   240 by analz_sees_tac;
   247 by (ALLGOALS
   241 by (ALLGOALS
   248     (asm_simp_tac 
   242     (asm_simp_tac 
   249      (!simpset addsimps [not_parts_not_analz, analz_insert_freshK]
   243      (!simpset addsimps [analz_insert_eq, not_parts_not_analz, 
       
   244 			 analz_insert_freshK]
   250                setloop split_tac [expand_if])));
   245                setloop split_tac [expand_if])));
       
   246 (*Oops*)
       
   247 by (blast_tac (!claset addDs [unique_session_keys]) 3);
   251 (*YM3*)
   248 (*YM3*)
   252 by (blast_tac (!claset delrules [impCE]
   249 by (blast_tac (!claset delrules [impCE]
   253                        addSEs sees_Spy_partsEs
   250                        addSEs sees_Spy_partsEs
   254                        addIs [impOfSubs analz_subset_parts]) 2);
   251                        addIs [impOfSubs analz_subset_parts]) 2);
   255 (*OR4, Fake*) 
   252 (*Fake*) 
   256 by (REPEAT_FIRST spy_analz_tac);
   253 by (spy_analz_tac 1);
   257 (*Oops*)
       
   258 by (blast_tac (!claset addDs [unique_session_keys]) 1);
       
   259 val lemma = result() RS mp RS mp RSN(2,rev_notE);
   254 val lemma = result() RS mp RS mp RSN(2,rev_notE);
   260 
   255 
   261 
   256 
   262 (*Final version*)
   257 (*Final version*)
   263 goal thy 
   258 goal thy 
   264  "!!evs. [| Says Server A                                         \
   259  "!!evs. [| Says Server A                                         \
   265 \              {|Crypt (shrK A) {|Agent B, Key K, NA, NB|},       \
   260 \              {|Crypt (shrK A) {|Agent B, Key K, na, nb|},       \
   266 \                Crypt (shrK B) {|Agent A, Key K|}|}              \
   261 \                Crypt (shrK B) {|Agent A, Key K|}|}              \
   267 \             : set_of_list evs;                                  \
   262 \             : set_of_list evs;                                  \
   268 \           Says A Spy {|NA, NB, Key K|} ~: set_of_list evs;      \
   263 \           Says A Spy {|na, nb, Key K|} ~: set_of_list evs;      \
   269 \           A ~: lost;  B ~: lost;  evs : yahalom lost |]         \
   264 \           A ~: lost;  B ~: lost;  evs : yahalom lost |]         \
   270 \        ==> Key K ~: analz (sees lost Spy evs)";
   265 \        ==> Key K ~: analz (sees lost Spy evs)";
   271 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1);
   266 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1);
   272 by (blast_tac (!claset addSEs [lemma]) 1);
   267 by (blast_tac (!claset addSEs [lemma]) 1);
   273 qed "Spy_not_see_encrypted_key";
   268 qed "Spy_not_see_encrypted_key";
   275 
   270 
   276 (*And other agents don't see the key either.*)
   271 (*And other agents don't see the key either.*)
   277 goal thy 
   272 goal thy 
   278  "!!evs. [| C ~: {A,B,Server};                                    \
   273  "!!evs. [| C ~: {A,B,Server};                                    \
   279 \           Says Server A                                         \
   274 \           Says Server A                                         \
   280 \              {|Crypt (shrK A) {|Agent B, Key K, NA, NB|},       \
   275 \              {|Crypt (shrK A) {|Agent B, Key K, na, nb|},       \
   281 \                Crypt (shrK B) {|Agent A, Key K|}|}              \
   276 \                Crypt (shrK B) {|Agent A, Key K|}|}              \
   282 \             : set_of_list evs;                                  \
   277 \             : set_of_list evs;                                  \
   283 \           Says A Spy {|NA, NB, Key K|} ~: set_of_list evs;      \
   278 \           Says A Spy {|na, nb, Key K|} ~: set_of_list evs;      \
   284 \           A ~: lost;  B ~: lost;  evs : yahalom lost |]         \
   279 \           A ~: lost;  B ~: lost;  evs : yahalom lost |]         \
   285 \        ==> Key K ~: analz (sees lost C evs)";
   280 \        ==> Key K ~: analz (sees lost C evs)";
   286 by (rtac (subset_insertI RS sees_mono RS analz_mono RS contra_subsetD) 1);
   281 by (rtac (subset_insertI RS sees_mono RS analz_mono RS contra_subsetD) 1);
   287 by (rtac (sees_lost_agent_subset_sees_Spy RS analz_mono RS contra_subsetD) 1);
   282 by (rtac (sees_lost_agent_subset_sees_Spy RS analz_mono RS contra_subsetD) 1);
   288 by (FIRSTGOAL (rtac Spy_not_see_encrypted_key));
   283 by (FIRSTGOAL (rtac Spy_not_see_encrypted_key));
   306 
   301 
   307 (** Security Guarantee for A upon receiving YM3 **)
   302 (** Security Guarantee for A upon receiving YM3 **)
   308 
   303 
   309 (*If the encrypted message appears then it originated with the Server*)
   304 (*If the encrypted message appears then it originated with the Server*)
   310 goal thy
   305 goal thy
   311  "!!evs. [| Crypt (shrK A) {|Agent B, Key K, NA, NB|}                  \
   306  "!!evs. [| Crypt (shrK A) {|Agent B, Key K, na, nb|}                  \
   312 \            : parts (sees lost Spy evs);                              \
   307 \            : parts (sees lost Spy evs);                              \
   313 \           A ~: lost;  evs : yahalom lost |]                          \
   308 \           A ~: lost;  evs : yahalom lost |]                          \
   314 \         ==> Says Server A                                            \
   309 \         ==> Says Server A                                            \
   315 \              {|Crypt (shrK A) {|Agent B, Key K, NA, NB|},            \
   310 \              {|Crypt (shrK A) {|Agent B, Key K, na, nb|},            \
   316 \                Crypt (shrK B) {|Agent A, Key K|}|}                   \
   311 \                Crypt (shrK B) {|Agent A, Key K|}|}                   \
   317 \             : set_of_list evs";
   312 \             : set_of_list evs";
   318 by (etac rev_mp 1);
   313 by (etac rev_mp 1);
   319 by parts_induct_tac;
   314 by parts_induct_tac;
   320 by (Fake_parts_insert_tac 1);
   315 by (Fake_parts_insert_tac 1);
   441 (*Base*)
   436 (*Base*)
   442 by (Blast_tac 1);
   437 by (Blast_tac 1);
   443 (*Fake*) 
   438 (*Fake*) 
   444 by (spy_analz_tac 1);
   439 by (spy_analz_tac 1);
   445 (*YM4*)  (** LEVEL 7 **)
   440 (*YM4*)  (** LEVEL 7 **)
   446 by (asm_simp_tac    (*X contributes nothing to the result of analz*)
       
   447     (analz_image_freshK_ss addsimps
       
   448      ([ball_conj_distrib, analz_image_freshK, 
       
   449        analz_insert_eq, impOfSubs (Un_upper2 RS analz_mono)])) 1);
       
   450 by (not_lost_tac "A" 1);
   441 by (not_lost_tac "A" 1);
   451 by (dtac (Says_imp_sees_Spy' RS parts.Inj RS parts.Fst RS A_trusts_YM3) 1
   442 by (dtac (Says_imp_sees_Spy' RS parts.Inj RS parts.Fst RS A_trusts_YM3) 1
   452     THEN REPEAT (assume_tac 1));
   443     THEN REPEAT (assume_tac 1));
   453 by (blast_tac (!claset addIs [KeyWithNonceI]) 1);
   444 by (blast_tac (!claset addIs [KeyWithNonceI]) 1);
   454 qed_spec_mp "Nonce_secrecy";
   445 qed_spec_mp "Nonce_secrecy";
   559 by (ALLGOALS
   550 by (ALLGOALS
   560     (asm_simp_tac 
   551     (asm_simp_tac 
   561      (!simpset addsimps ([analz_insert_eq, not_parts_not_analz,
   552      (!simpset addsimps ([analz_insert_eq, not_parts_not_analz,
   562                           analz_insert_freshK] @ pushes)
   553                           analz_insert_freshK] @ pushes)
   563                setloop split_tac [expand_if])));
   554                setloop split_tac [expand_if])));
       
   555 (*Prove YM3 by showing that no NB can also be an NA*)
       
   556 by (blast_tac (!claset addDs [Says_imp_sees_Spy' RS parts.Inj]
       
   557 	               addSEs [MPair_parts]
       
   558 		       addDs  [no_nonce_YM1_YM2, Says_unique_NB']) 4
       
   559     THEN flexflex_tac);
       
   560 (*YM2: similar freshness reasoning*) 
       
   561 by (blast_tac (!claset addSEs partsEs
       
   562 		       addDs  [Says_imp_sees_Spy' RS analz.Inj,
       
   563 			       impOfSubs analz_subset_parts]) 3);
   564 (*YM1: NB=NA is impossible anyway, but NA is secret because it is fresh!*)
   564 (*YM1: NB=NA is impossible anyway, but NA is secret because it is fresh!*)
   565 by (blast_tac (!claset addSIs [parts_insertI]
   565 by (blast_tac (!claset addSIs [parts_insertI]
   566                        addSEs sees_Spy_partsEs) 2);
   566                        addSEs sees_Spy_partsEs) 2);
   567 (*YM2: similar freshness reasoning*) 
       
   568 by (blast_tac (!claset addSEs partsEs
       
   569 		       addDs  [Says_imp_sees_Spy' RS analz.Inj,
       
   570 			       impOfSubs analz_subset_parts]) 2);
       
   571 (*Prove YM3 by showing that no NB can also be an NA*)
       
   572 by (blast_tac (!claset addDs [Says_imp_sees_Spy' RS parts.Inj]
       
   573 	               addSEs [MPair_parts]
       
   574 		       addDs  [no_nonce_YM1_YM2, Says_unique_NB']) 2
       
   575     THEN flexflex_tac);
       
   576 (*Fake*)
   567 (*Fake*)
   577 by (spy_analz_tac 1);
   568 by (spy_analz_tac 1);
   578 (** LEVEL 7: YM4 and Oops remain **)
   569 (** LEVEL 7: YM4 and Oops remain **)
   579 (*YM4: key K is visible to Spy, contradicting session key secrecy theorem*) 
   570 (*YM4: key K is visible to Spy, contradicting session key secrecy theorem*) 
   580 by (REPEAT (Safe_step_tac 1));
   571 by (REPEAT (Safe_step_tac 1));