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. **) |
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"; |