src/HOL/Auth/Recur.ML
changeset 2481 ee461c8bc9c3
parent 2455 9c4444bfd44e
child 2485 c4368c967c56
equal deleted inserted replaced
2480:f9be937df511 2481:ee461c8bc9c3
    17 	ONE theorem would be more elegant and faster!
    17 	ONE theorem would be more elegant and faster!
    18 	By induction on a list of agents (no repetitions)
    18 	By induction on a list of agents (no repetitions)
    19 **)
    19 **)
    20 
    20 
    21 (*Simplest case: Alice goes directly to the server*)
    21 (*Simplest case: Alice goes directly to the server*)
    22 goal thy 
    22 goal thy
    23  "!!A. A ~= Server   \
    23  "!!A. A ~= Server   \
    24 \ ==> EX K NA. EX evs: recur lost.          \
    24 \ ==> EX K NA. EX evs: recur lost.          \
    25 \     Says Server A {|Agent A,              \
    25 \     Says Server A {|Agent A,              \
    26 \                     Crypt (shrK A) {|Key K, Agent Server, Nonce NA|}, \
    26 \                     Crypt (shrK A) {|Key K, Agent Server, Nonce NA|}, \
    27 \                       Agent Server|}      \
    27 \                       Agent Server|}      \
    28 \         : set_of_list evs";
    28 \         : set_of_list evs";
    29 by (REPEAT (resolve_tac [exI,bexI] 1));
    29 by (REPEAT (resolve_tac [exI,bexI] 1));
    30 by (rtac (recur.Nil RS recur.RA1 RS 
    30 by (rtac (recur.Nil RS recur.RA1 RS 
    31 	  (respond.One RSN (4,recur.RA3))) 2);
    31 	  (respond.One RSN (4,recur.RA3))) 2);
    32 by (ALLGOALS (simp_tac (!simpset setsolver safe_solver)));
    32 by (REPEAT
    33 by (REPEAT_FIRST (eq_assume_tac ORELSE' resolve_tac [refl, conjI]));
    33     (ALLGOALS (asm_simp_tac (!simpset setsolver safe_solver))
       
    34      THEN
       
    35      REPEAT_FIRST (eq_assume_tac ORELSE' resolve_tac [refl, conjI])));
    34 result();
    36 result();
    35 
    37 
    36 
    38 
    37 (*Case two: Alice, Bob and the server*)
    39 (*Case two: Alice, Bob and the server*)
    38 goal thy 
    40 goal thy
    39  "!!A B. [| A ~= B; A ~= Server; B ~= Server |]   \
    41  "!!A B. [| A ~= B; A ~= Server; B ~= Server |]   \
    40 \ ==> EX K. EX NA. EX evs: recur lost.          \
    42 \ ==> EX K. EX NA. EX evs: recur lost.          \
    41 \       Says B A {|Agent A, Crypt (shrK A) {|Key K, Agent B, Nonce NA|}, \
    43 \       Says B A {|Agent A, Crypt (shrK A) {|Key K, Agent B, Nonce NA|}, \
    42 \                       Agent Server|}                          \
    44 \                       Agent Server|}                          \
    43 \         : set_of_list evs";
    45 \         : set_of_list evs";
    44 by (REPEAT (resolve_tac [exI,bexI] 1));
    46 by (REPEAT (resolve_tac [exI,bexI] 1));
    45 by (rtac (recur.Nil RS recur.RA1 RS recur.RA2 RS 
    47 by (rtac (recur.Nil RS recur.RA1 RS recur.RA2 RS 
    46 	  (respond.One RS respond.Cons RSN (4,recur.RA3)) RS
    48 	  (respond.One RS respond.Cons RSN (4,recur.RA3)) RS
    47 	  recur.RA4) 2);
    49 	  recur.RA4) 2);
       
    50 bw HPair_def;
    48 by (REPEAT
    51 by (REPEAT
    49     (REPEAT_FIRST (eq_assume_tac ORELSE' resolve_tac [refl, conjI])
    52     (REPEAT_FIRST (eq_assume_tac ORELSE' resolve_tac [refl, conjI])
    50      THEN
    53      THEN
    51      ALLGOALS (asm_simp_tac (!simpset setsolver safe_solver))));
    54      ALLGOALS (asm_simp_tac (!simpset setsolver safe_solver))));
    52 result();
    55 result();
    53 
    56 
    54 
    57 
    55 (*Case three: Alice, Bob, Charlie and the server*)
    58 (*Case three: Alice, Bob, Charlie and the server*)
    56 goal thy 
    59 goal thy
    57  "!!A B. [| A ~= B; A ~= Server; B ~= Server |]   \
    60  "!!A B. [| A ~= B; A ~= Server; B ~= Server |]   \
    58 \ ==> EX K. EX NA. EX evs: recur lost.          \
    61 \ ==> EX K. EX NA. EX evs: recur lost.          \
    59 \       Says B A {|Agent A, Crypt (shrK A) {|Key K, Agent B, Nonce NA|}, \
    62 \       Says B A {|Agent A, Crypt (shrK A) {|Key K, Agent B, Nonce NA|}, \
    60 \                       Agent Server|}                          \
    63 \                       Agent Server|}                          \
    61 \         : set_of_list evs";
    64 \         : set_of_list evs";
    62 by (REPEAT (resolve_tac [exI,bexI] 1));
    65 by (REPEAT (resolve_tac [exI,bexI] 1));
    63 by (rtac (recur.Nil RS recur.RA1 RS recur.RA2 RS recur.RA2 RS 
    66 by (rtac (recur.Nil RS recur.RA1 RS recur.RA2 RS recur.RA2 RS 
    64 	  (respond.One RS respond.Cons RS respond.Cons RSN
    67 	  (respond.One RS respond.Cons RS respond.Cons RSN
    65 	   (4,recur.RA3)) RS recur.RA4 RS recur.RA4) 2);
    68 	   (4,recur.RA3)) RS recur.RA4 RS recur.RA4) 2);
       
    69 bw HPair_def;
    66 by (REPEAT	(*SLOW: 37 seconds*)
    70 by (REPEAT	(*SLOW: 37 seconds*)
    67     (REPEAT_FIRST (eq_assume_tac ORELSE' resolve_tac [refl, conjI])
    71     (REPEAT_FIRST (eq_assume_tac ORELSE' resolve_tac [refl, conjI])
    68      THEN
    72      THEN
    69      ALLGOALS (asm_simp_tac (!simpset setsolver safe_solver))));
    73      ALLGOALS (asm_simp_tac (!simpset setsolver safe_solver))));
    70 by (ALLGOALS 
    74 by (ALLGOALS 
   311     dres_inst_tac [("lost","lost")] RA2_analz_sees_Spy 4 THEN 
   315     dres_inst_tac [("lost","lost")] RA2_analz_sees_Spy 4 THEN 
   312     forward_tac [respond_imp_responses] 5                THEN
   316     forward_tac [respond_imp_responses] 5                THEN
   313     dres_inst_tac [("lost","lost")] RA4_analz_sees_Spy 6;
   317     dres_inst_tac [("lost","lost")] RA4_analz_sees_Spy 6;
   314 
   318 
   315 
   319 
       
   320 Delsimps [image_insert];
       
   321 
   316 (** Session keys are not used to encrypt other session keys **)
   322 (** Session keys are not used to encrypt other session keys **)
   317 
   323 
   318 (*Version for "responses" relation.  Handles case RA3 in the theorem below.  
   324 (*Version for "responses" relation.  Handles case RA3 in the theorem below.  
   319   Note that it holds for *any* set H (not just "sees lost Spy evs")
   325   Note that it holds for *any* set H (not just "sees lost Spy evs")
   320   satisfying the inductive hypothesis.*)
   326   satisfying the inductive hypothesis.*)
   337 goal thy  
   343 goal thy  
   338  "!!evs. evs : recur lost ==>                                            \
   344  "!!evs. evs : recur lost ==>                                            \
   339 \  ALL K I. (Key K : analz (Key``(newK``I) Un (sees lost Spy evs))) = \
   345 \  ALL K I. (Key K : analz (Key``(newK``I) Un (sees lost Spy evs))) = \
   340 \           (K : newK``I | Key K : analz (sees lost Spy evs))";
   346 \           (K : newK``I | Key K : analz (sees lost Spy evs))";
   341 by (etac recur.induct 1);
   347 by (etac recur.induct 1);
       
   348 be subst 4;	(*RA2: DELETE needless definition of PA!*)
   342 by analz_Fake_tac;
   349 by analz_Fake_tac;
   343 be ssubst 4;	(*RA2: DELETE needless definition of PA!*)
       
   344 by (REPEAT_FIRST (ares_tac [allI, analz_image_newK_lemma]));
   350 by (REPEAT_FIRST (ares_tac [allI, analz_image_newK_lemma]));
   345 by (ALLGOALS (asm_simp_tac (!simpset addsimps [resp_analz_image_newK_lemma])));
   351 by (ALLGOALS (asm_simp_tac (!simpset addsimps [resp_analz_image_newK_lemma])));
   346 (*Base*)
   352 (*Base*)
   347 by (fast_tac (!claset addIs [image_eqI] addss (!simpset)) 1);
   353 by (fast_tac (!claset addIs [image_eqI] addss (!simpset)) 1);
   348 (*RA4, RA2, Fake*) 
   354 (*RA4, RA2, Fake*) 
   379 goal thy "!!i. evs : recur lost ==>              \
   385 goal thy "!!i. evs : recur lost ==>              \
   380 \                length evs <= i -->             \
   386 \                length evs <= i -->             \
   381 \                (Nonce (newN i) : parts {X} --> \
   387 \                (Nonce (newN i) : parts {X} --> \
   382 \                 Hash X ~: parts (sees lost Spy evs))";
   388 \                 Hash X ~: parts (sees lost Spy evs))";
   383 be recur.induct 1;
   389 be recur.induct 1;
   384 be ssubst 4;	(*RA2: DELETE needless definition of PA!*)
   390 be subst 4;	(*RA2: DELETE needless definition of PA!*)
   385 by parts_Fake_tac;
   391 by parts_Fake_tac;
   386 (*RA3 requires a further induction*)
   392 (*RA3 requires a further induction*)
   387 be responses.induct 5;
   393 be responses.induct 5;
   388 by (ALLGOALS Asm_simp_tac);
   394 by (ALLGOALS Asm_simp_tac);
   389 (*RA2*)
   395 (*RA2*)
   414  "!!evs. [| evs : recur lost; A ~: lost |]               \
   420  "!!evs. [| evs : recur lost; A ~: lost |]               \
   415 \ ==> EX B' P'. ALL B P.    \
   421 \ ==> EX B' P'. ALL B P.    \
   416 \        Hash {|Key(shrK A), Agent A, Agent B, Nonce NA, P|} \
   422 \        Hash {|Key(shrK A), Agent A, Agent B, Nonce NA, P|} \
   417 \          : parts (sees lost Spy evs)  -->  B=B' & P=P'";
   423 \          : parts (sees lost Spy evs)  -->  B=B' & P=P'";
   418 be recur.induct 1;
   424 be recur.induct 1;
   419 be ssubst 4;	(*RA2: DELETE needless definition of PA!*)
   425 be subst 4;	(*RA2: DELETE needless definition of PA!*)
   420 (*For better simplification of RA2*)
   426 (*For better simplification of RA2*)
   421 by (res_inst_tac [("x1","XA")] (insert_commute RS ssubst) 4);
   427 by (res_inst_tac [("x1","XA")] (insert_commute RS ssubst) 4);
   422 by parts_Fake_tac;
   428 by parts_Fake_tac;
   423 (*RA3 requires a further induction*)
   429 (*RA3 requires a further induction*)
   424 be responses.induct 5;
   430 be responses.induct 5;
   429 (*Fake*)
   435 (*Fake*)
   430 by (best_tac (!claset addSIs [exI]
   436 by (best_tac (!claset addSIs [exI]
   431                       addDs [impOfSubs analz_subset_parts,
   437                       addDs [impOfSubs analz_subset_parts,
   432 			     impOfSubs Fake_parts_insert]
   438 			     impOfSubs Fake_parts_insert]
   433 		      addss (!simpset)) 2);
   439 		      addss (!simpset)) 2);
   434 (*Base*)
   440 (*Base*) (** LEVEL 9 **)
   435 by (fast_tac (!claset addss (!simpset)) 1);
   441 by (fast_tac (!claset addss (!simpset)) 1);
   436 
       
   437 by (ALLGOALS (simp_tac (!simpset addsimps [all_conj_distrib]))); 
   442 by (ALLGOALS (simp_tac (!simpset addsimps [all_conj_distrib]))); 
   438 (*RA1: creation of new Nonce.  Move assertion into global context*)
   443 (*RA1: creation of new Nonce.  Move assertion into global context*)
   439 by (expand_case_tac "NA = ?y" 1);
   444 by (expand_case_tac "NA = ?y" 1);
   440 by (best_tac (!claset addSIs [exI]
   445 by (best_tac (!claset addSIs [exI]
   441                       addEs  [Hash_new_nonces_not_seen]
   446                       addEs  [Hash_new_nonces_not_seen]
   448 		      addEs  [Hash_new_nonces_not_seen]
   453 		      addEs  [Hash_new_nonces_not_seen]
   449 		      addss  (!simpset)) 1);
   454 		      addss  (!simpset)) 1);
   450 by (best_tac (!claset addss  (!simpset)) 1);
   455 by (best_tac (!claset addss  (!simpset)) 1);
   451 val lemma = result();
   456 val lemma = result();
   452 
   457 
   453 goal thy 
   458 goalw thy [HPair_def]
   454  "!!evs.[| Hash {|Key(shrK A), Agent A, Agent B, Nonce NA, P|}   \
   459  "!!evs.[| HPair (Key(shrK A)) {|Agent A, Agent B, Nonce NA, P|}   \
   455 \            : parts (sees lost Spy evs);                        \
   460 \            : parts (sees lost Spy evs);                        \
   456 \          Hash {|Key(shrK A), Agent A, Agent B', Nonce NA, P'|} \
   461 \          HPair (Key(shrK A)) {|Agent A, Agent B', Nonce NA, P'|} \
   457 \            : parts (sees lost Spy evs);                        \
   462 \            : parts (sees lost Spy evs);                        \
   458 \          evs : recur lost;  A ~: lost |]                      \
   463 \          evs : recur lost;  A ~: lost |]                      \
   459 \        ==> B=B' & P=P'";
   464 \        ==> B=B' & P=P'";
       
   465 by (REPEAT (eresolve_tac partsEs 1));
   460 by (prove_unique_tac lemma 1);
   466 by (prove_unique_tac lemma 1);
   461 qed "unique_NA";
   467 qed "unique_NA";
   462 
   468 
   463 
   469 
   464 (*** Lemmas concerning the Server's response
   470 (*** Lemmas concerning the Server's response
   465       (relations "respond" and "responses") 
   471       (relations "respond" and "responses") 
   466 ***)
   472 ***)
   467 
       
   468 (*The response never contains Hashes*)
       
   469 (*NEEDED????????????????*)
       
   470 goal thy
       
   471  "!!evs. (j,PB,RB) : respond i \
       
   472 \        ==> Hash {|Key (shrK B), M|} : parts (insert RB H) --> \
       
   473 \            Hash {|Key (shrK B), M|} : parts H";
       
   474 be (respond_imp_responses RS responses.induct) 1;
       
   475 by (Auto_tac());
       
   476 bind_thm ("Hash_in_parts_respond", result() RSN (2, rev_mp));
       
   477 
       
   478 
   473 
   479 goal thy
   474 goal thy
   480  "!!evs. [| RB : responses i;  evs : recur lost |] \
   475  "!!evs. [| RB : responses i;  evs : recur lost |] \
   481 \ ==> (Key (shrK B) : analz (insert RB (sees lost Spy evs))) = (B:lost)";
   476 \ ==> (Key (shrK B) : analz (insert RB (sees lost Spy evs))) = (B:lost)";
   482 be responses.induct 1;
   477 be responses.induct 1;
   554 goal thy 
   549 goal thy 
   555  "!!RB. [| Crypt (shrK A) {|Key K, Agent B, N|} : parts {RB};    \
   550  "!!RB. [| Crypt (shrK A) {|Key K, Agent B, N|} : parts {RB};    \
   556 \          Crypt (shrK A') {|Key K, Agent B', N'|} : parts {RB};   \
   551 \          Crypt (shrK A') {|Key K, Agent B', N'|} : parts {RB};   \
   557 \          (j,PB,RB) : respond i |]               \
   552 \          (j,PB,RB) : respond i |]               \
   558 \ ==>   (A'=A & B'=B) | (A'=B & B'=A)";
   553 \ ==>   (A'=A & B'=B) | (A'=B & B'=A)";
   559 by (prove_unique_tac lemma 1);	(*33 seconds, due to the disjunctions*)
   554 by (prove_unique_tac lemma 1);	(*50 seconds??, due to the disjunctions*)
   560 qed "unique_session_keys";
   555 qed "unique_session_keys";
   561 
   556 
   562 
   557 
   563 (** Crucial secrecy property: Spy does not see the keys sent in msg RA3
   558 (** Crucial secrecy property: Spy does not see the keys sent in msg RA3
   564     Does not in itself guarantee security: an attack could violate 
   559     Does not in itself guarantee security: an attack could violate 
   565     the premises, e.g. by having A=Spy **)
   560     the premises, e.g. by having A=Spy **)
   566 
   561 
   567 goal thy 
   562 goal thy 
   568  "!!j. (j, {|Hash {|Key(shrK A), Agent A, B, NA, P|}, X|}, RA) : respond i \
   563  "!!j. (j, HPair (Key(shrK A)) {|Agent A, B, NA, P|}, RA) : respond i \
   569 \ ==> Crypt (shrK A) {|Key (newK2 (i,j)), B, NA|} : parts {RA}";
   564 \ ==> Crypt (shrK A) {|Key (newK2 (i,j)), B, NA|} : parts {RA}";
   570 be respond.elim 1;
   565 be respond.elim 1;
   571 by (ALLGOALS Asm_full_simp_tac);
   566 by (ALLGOALS Asm_full_simp_tac);
   572 qed "newK2_respond_lemma";
   567 qed "newK2_respond_lemma";
   573 
   568 
   577 \        ==> ALL A A' N. A ~: lost & A' ~: lost -->  \
   572 \        ==> ALL A A' N. A ~: lost & A' ~: lost -->  \
   578 \            Crypt (shrK A) {|Key K, Agent A', N|} : parts{RB} -->  \
   573 \            Crypt (shrK A) {|Key K, Agent A', N|} : parts{RB} -->  \
   579 \            Key K ~: analz (insert RB (sees lost Spy evs))";
   574 \            Key K ~: analz (insert RB (sees lost Spy evs))";
   580 be respond.induct 1;
   575 be respond.induct 1;
   581 by (forward_tac [respond_imp_responses] 2);
   576 by (forward_tac [respond_imp_responses] 2);
   582 by (ALLGOALS
   577 by (ALLGOALS (*4 MINUTES???*)
   583     (asm_simp_tac 
   578     (asm_simp_tac 
   584      (!simpset addsimps 
   579      (!simpset addsimps 
   585 	  ([analz_image_newK, not_parts_not_analz,
   580 	  ([analz_image_newK, not_parts_not_analz,
   586 	    read_instantiate [("H", "?ff``?xx")] parts_insert,
   581 	    read_instantiate [("H", "?ff``?xx")] parts_insert,
   587 	    Un_assoc RS sym, resp_analz_image_newK,
   582 	    Un_assoc RS sym, resp_analz_image_newK,
   613  "!!evs. [| A ~: lost;  A' ~: lost;  evs : recur lost |]            \
   608  "!!evs. [| A ~: lost;  A' ~: lost;  evs : recur lost |]            \
   614 \        ==> Says Server B RB : set_of_list evs -->                 \
   609 \        ==> Says Server B RB : set_of_list evs -->                 \
   615 \            Crypt (shrK A) {|Key K, Agent A', N|} : parts{RB} -->  \
   610 \            Crypt (shrK A) {|Key K, Agent A', N|} : parts{RB} -->  \
   616 \            Key K ~: analz (sees lost Spy evs)";
   611 \            Key K ~: analz (sees lost Spy evs)";
   617 by (etac recur.induct 1);
   612 by (etac recur.induct 1);
       
   613 be subst 4;	(*RA2: DELETE needless definition of PA!*)
   618 by analz_Fake_tac;
   614 by analz_Fake_tac;
   619 be ssubst 4;	(*RA2: DELETE needless definition of PA!*)
       
   620 by (ALLGOALS
   615 by (ALLGOALS
   621     (asm_simp_tac
   616     (asm_simp_tac
   622      (!simpset addsimps [not_parts_not_analz, analz_insert_Key_newK] 
   617      (!simpset addsimps [not_parts_not_analz, analz_insert_Key_newK] 
   623                setloop split_tac [expand_if])));
   618                setloop split_tac [expand_if])));
   624 (*RA4*)
   619 (*RA4*)
   652 qed "Agent_not_see_encrypted_key";
   647 qed "Agent_not_see_encrypted_key";
   653 
   648 
   654 
   649 
   655 (**** Authenticity properties for Agents ****)
   650 (**** Authenticity properties for Agents ****)
   656 
   651 
       
   652 (*The response never contains Hashes*)
       
   653 (*NEEDED????????????????*)
       
   654 goal thy
       
   655  "!!evs. (j,PB,RB) : respond i \
       
   656 \        ==> Hash {|Key (shrK B), M|} : parts (insert RB H) --> \
       
   657 \            Hash {|Key (shrK B), M|} : parts H";
       
   658 be (respond_imp_responses RS responses.induct) 1;
       
   659 by (Auto_tac());
       
   660 bind_thm ("Hash_in_parts_respond", result() RSN (2, rev_mp));
       
   661 
   657 (*NEEDED????????????????*)
   662 (*NEEDED????????????????*)
   658 (*Only RA1 or RA2 can have caused such a part of a message to appear.*)
   663 (*Only RA1 or RA2 can have caused such a part of a message to appear.*)
   659 goal thy 
   664 goalw thy [HPair_def]
   660  "!!evs. [| Hash {|Key(shrK A), Agent A, Agent B, NA, P|}         \
   665  "!!evs. [| Hash {|Key(shrK A), Agent A, Agent B, NA, P|}         \
   661 \             : parts (sees lost Spy evs);                        \
   666 \             : parts (sees lost Spy evs);                        \
   662 \            A ~: lost;  evs : recur lost |]                        \
   667 \            A ~: lost;  evs : recur lost |]                        \
   663 \        ==> Says A B {|Hash{|Key(shrK A), Agent A, Agent B, NA, P|},  \
   668 \        ==> Says A B (HPair (Key(shrK A)) {|Agent A, Agent B, NA, P|})  \
   664 \                       Agent A, Agent B, NA, P|}  \
       
   665 \             : set_of_list evs";
   669 \             : set_of_list evs";
   666 be rev_mp 1;
   670 be rev_mp 1;
   667 by (parts_induct_tac 1);
   671 by (parts_induct_tac 1);
   668 (*RA3*)
   672 (*RA3*)
   669 by (fast_tac (!claset addSDs [Hash_in_parts_respond]) 2);
   673 by (fast_tac (!claset addSDs [Hash_in_parts_respond]) 2);
   672     (res_inst_tac [("x1","XA")] (insert_commute RS ssubst) 1));
   676     (res_inst_tac [("x1","XA")] (insert_commute RS ssubst) 1));
   673 by (best_tac (!claset addSEs partsEs 
   677 by (best_tac (!claset addSEs partsEs 
   674                       addDs [parts_cut]
   678                       addDs [parts_cut]
   675                       addss  (!simpset)) 1);
   679                       addss  (!simpset)) 1);
   676 qed_spec_mp "Hash_auth_sender";
   680 qed_spec_mp "Hash_auth_sender";
   677 
       
   678 
       
   679 (*NEEDED????????????????*)
       
   680 goal thy "!!i. {|Hash {|Key (shrK Server), M|}, M|} : responses i ==> R";
       
   681 be setup_induction 1;
       
   682 be responses.induct 1;
       
   683 by (ALLGOALS Asm_simp_tac); 
       
   684 qed "responses_no_Hash_Server";
       
   685 
   681 
   686 
   682 
   687 val nonce_not_seen_now = le_refl RSN (2, new_nonces_not_seen) RSN (2,rev_notE);
   683 val nonce_not_seen_now = le_refl RSN (2, new_nonces_not_seen) RSN (2,rev_notE);
   688 
   684 
   689 
   685