49 @{term "True\<noteq>False"}, no agent has identical signing and encryption keys*} |
52 @{term "True\<noteq>False"}, no agent has identical signing and encryption keys*} |
50 specification (publicKey) |
53 specification (publicKey) |
51 injective_publicKey: |
54 injective_publicKey: |
52 "publicKey b A = publicKey c A' ==> b=c & A=A'" |
55 "publicKey b A = publicKey c A' ==> b=c & A=A'" |
53 apply (rule exI [of _ "%b A. 2 * agent_case 0 (\<lambda>n. n + 2) 1 A + (if b then 1 else 0)"]) |
56 apply (rule exI [of _ "%b A. 2 * agent_case 0 (\<lambda>n. n + 2) 1 A + (if b then 1 else 0)"]) |
54 apply (auto simp add: inj_on_def split: agent.split) |
57 apply (auto simp add: inj_on_def split: agent.split, presburger+) |
55 apply presburger+ |
|
56 (*faster would be this: |
58 (*faster would be this: |
57 apply (drule_tac f="%x. x mod 2" in arg_cong, simp add: mod_Suc)+ |
59 apply (drule_tac f="%x. x mod 2" in arg_cong, simp add: mod_Suc)+ |
58 *) |
60 *) |
59 done |
61 done |
60 |
62 |
135 sym_shrK [iff]: "shrK X \<in> symKeys" --{*All shared keys are symmetric*} |
137 sym_shrK [iff]: "shrK X \<in> symKeys" --{*All shared keys are symmetric*} |
136 |
138 |
137 (*Injectiveness: Agents' long-term keys are distinct.*) |
139 (*Injectiveness: Agents' long-term keys are distinct.*) |
138 declare inj_shrK [THEN inj_eq, iff] |
140 declare inj_shrK [THEN inj_eq, iff] |
139 |
141 |
|
142 lemma invKey_shrK [simp]: "invKey (shrK A) = shrK A" |
|
143 by (simp add: invKey_K) |
|
144 |
|
145 lemma analz_shrK_Decrypt: |
|
146 "[| Crypt (shrK A) X \<in> analz H; Key(shrK A) \<in> analz H |] ==> X \<in> analz H" |
|
147 by auto |
|
148 |
|
149 lemma analz_Decrypt': |
|
150 "[| Crypt K X \<in> analz H; K \<in> symKeys; Key K \<in> analz H |] ==> X \<in> analz H" |
|
151 by (auto simp add: invKey_K) |
|
152 |
140 lemma priK_neq_shrK [iff]: "shrK A \<noteq> privateKey b C" |
153 lemma priK_neq_shrK [iff]: "shrK A \<noteq> privateKey b C" |
141 by (simp add: symKeys_neq_imp_neq) |
154 by (simp add: symKeys_neq_imp_neq) |
142 |
155 |
143 declare priK_neq_shrK [THEN not_sym, simp] |
156 declare priK_neq_shrK [THEN not_sym, simp] |
144 |
157 |
231 by (induct B, auto) |
247 by (induct B, auto) |
232 |
248 |
233 lemma Crypt_notin_used_empty [simp]: "Crypt K X \<notin> used []" |
249 lemma Crypt_notin_used_empty [simp]: "Crypt K X \<notin> used []" |
234 by (simp add: Crypt_notin_initState used_Nil) |
250 by (simp add: Crypt_notin_initState used_Nil) |
235 |
251 |
236 |
|
237 (*** Basic properties of shrK ***) |
252 (*** Basic properties of shrK ***) |
238 |
253 |
239 (*Agents see their own shared keys!*) |
254 (*Agents see their own shared keys!*) |
240 lemma shrK_in_initState [iff]: "Key (shrK A) \<in> initState A" |
255 lemma shrK_in_initState [iff]: "Key (shrK A) \<in> initState A" |
241 by (induct_tac "A", auto) |
256 by (induct_tac "A", auto) |
244 by (simp add: initState_subset_knows [THEN subsetD]) |
259 by (simp add: initState_subset_knows [THEN subsetD]) |
245 |
260 |
246 lemma shrK_in_used [iff]: "Key (shrK A) \<in> used evs" |
261 lemma shrK_in_used [iff]: "Key (shrK A) \<in> used evs" |
247 by (rule initState_into_used, blast) |
262 by (rule initState_into_used, blast) |
248 |
263 |
|
264 |
249 (** Fresh keys never clash with long-term shared keys **) |
265 (** Fresh keys never clash with long-term shared keys **) |
250 |
266 |
251 (*Used in parts_induct_tac and analz_Fake_tac to distinguish session keys |
267 (*Used in parts_induct_tac and analz_Fake_tac to distinguish session keys |
252 from long-term shared keys*) |
268 from long-term shared keys*) |
253 lemma Key_not_used: "Key K \<notin> used evs ==> K \<notin> range shrK" |
269 lemma Key_not_used [simp]: "Key K \<notin> used evs ==> K \<notin> range shrK" |
254 by blast |
270 by blast |
255 |
271 |
256 lemma shrK_neq: "Key K \<notin> used evs ==> shrK B \<noteq> K" |
272 lemma shrK_neq: "Key K \<notin> used evs ==> shrK B \<noteq> K" |
257 by blast |
273 by blast |
258 |
274 |
|
275 declare shrK_neq [THEN not_sym, simp] |
259 |
276 |
260 |
277 |
261 subsection{*Function @{term spies} *} |
278 subsection{*Function @{term spies} *} |
262 |
279 |
263 text{*Agents see their own private keys!*} |
280 text{*Agents see their own private keys!*} |
297 |
314 |
298 lemma privateKey_into_used [iff]: "Key (privateKey b A) \<in> used evs" |
315 lemma privateKey_into_used [iff]: "Key (privateKey b A) \<in> used evs" |
299 apply(rule initState_into_used) |
316 apply(rule initState_into_used) |
300 apply(rule priK_in_initState [THEN parts.Inj]) |
317 apply(rule priK_in_initState [THEN parts.Inj]) |
301 done |
318 done |
|
319 |
|
320 (*For case analysis on whether or not an agent is compromised*) |
|
321 lemma Crypt_Spy_analz_bad: |
|
322 "[| Crypt (shrK A) X \<in> analz (knows Spy evs); A \<in> bad |] |
|
323 ==> X \<in> analz (knows Spy evs)" |
|
324 by force |
302 |
325 |
303 |
326 |
304 subsection{*Fresh Nonces*} |
327 subsection{*Fresh Nonces*} |
305 |
328 |
306 lemma Nonce_notin_initState [iff]: "Nonce N \<notin> parts (initState B)" |
329 lemma Nonce_notin_initState [iff]: "Nonce N \<notin> parts (initState B)" |
342 val Key_not_used = thm "Key_not_used"; |
365 val Key_not_used = thm "Key_not_used"; |
343 val insert_Key_singleton = thm "insert_Key_singleton"; |
366 val insert_Key_singleton = thm "insert_Key_singleton"; |
344 val insert_Key_image = thm "insert_Key_image"; |
367 val insert_Key_image = thm "insert_Key_image"; |
345 *} |
368 *} |
346 |
369 |
347 (* |
370 |
348 val not_symKeys_pubK = thm "not_symKeys_pubK"; |
371 lemma Crypt_imp_keysFor :"[|Crypt K X \<in> H; K \<in> symKeys|] ==> K \<in> keysFor H" |
349 val not_symKeys_priK = thm "not_symKeys_priK"; |
|
350 val symKeys_neq_imp_neq = thm "symKeys_neq_imp_neq"; |
|
351 val analz_symKeys_Decrypt = thm "analz_symKeys_Decrypt"; |
|
352 val invKey_image_eq = thm "invKey_image_eq"; |
|
353 val pubK_image_eq = thm "pubK_image_eq"; |
|
354 val priK_pubK_image_eq = thm "priK_pubK_image_eq"; |
|
355 val keysFor_parts_initState = thm "keysFor_parts_initState"; |
|
356 val priK_in_initState = thm "priK_in_initState"; |
|
357 val spies_pubK = thm "spies_pubK"; |
|
358 val Spy_spies_bad = thm "Spy_spies_bad"; |
|
359 val Nonce_notin_initState = thm "Nonce_notin_initState"; |
|
360 val Nonce_notin_used_empty = thm "Nonce_notin_used_empty"; |
|
361 |
|
362 *) |
|
363 |
|
364 |
|
365 lemma invKey_K [simp]: "K \<in> symKeys ==> invKey K = K" |
|
366 by (simp add: symKeys_def) |
|
367 |
|
368 lemma Crypt_imp_keysFor :"[|K \<in> symKeys; Crypt K X \<in> H|] ==> K \<in> keysFor H" |
|
369 by (drule Crypt_imp_invKey_keysFor, simp) |
372 by (drule Crypt_imp_invKey_keysFor, simp) |
370 |
373 |
371 |
374 text{*Lemma for the trivial direction of the if-and-only-if of the |
372 subsection{*Specialized Methods for Possibility Theorems*} |
375 Session Key Compromise Theorem*} |
|
376 lemma analz_image_freshK_lemma: |
|
377 "(Key K \<in> analz (Key`nE \<union> H)) --> (K \<in> nE | Key K \<in> analz H) ==> |
|
378 (Key K \<in> analz (Key`nE \<union> H)) = (K \<in> nE | Key K \<in> analz H)" |
|
379 by (blast intro: analz_mono [THEN [2] rev_subsetD]) |
|
380 |
|
381 lemmas analz_image_freshK_simps = |
|
382 simp_thms mem_simps --{*these two allow its use with @{text "only:"}*} |
|
383 disj_comms |
|
384 image_insert [THEN sym] image_Un [THEN sym] empty_subsetI insert_subset |
|
385 analz_insert_eq Un_upper2 [THEN analz_mono, THEN subsetD] |
|
386 insert_Key_singleton |
|
387 Key_not_used insert_Key_image Un_assoc [THEN sym] |
373 |
388 |
374 ML |
389 ML |
375 {* |
390 {* |
376 val Nonce_supply1 = thm "Nonce_supply1"; |
391 val analz_image_freshK_lemma = thm "analz_image_freshK_lemma"; |
|
392 val analz_image_freshK_simps = thms "analz_image_freshK_simps"; |
|
393 |
|
394 val analz_image_freshK_ss = |
|
395 simpset() delsimps [image_insert, image_Un] |
|
396 delsimps [imp_disjL] (*reduces blow-up*) |
|
397 addsimps thms "analz_image_freshK_simps" |
|
398 *} |
|
399 |
|
400 method_setup analz_freshK = {* |
|
401 Method.no_args |
|
402 (Method.METHOD |
|
403 (fn facts => EVERY [REPEAT_FIRST (resolve_tac [allI, ballI, impI]), |
|
404 REPEAT_FIRST (rtac analz_image_freshK_lemma), |
|
405 ALLGOALS (asm_simp_tac analz_image_freshK_ss)])) *} |
|
406 "for proving the Session Key Compromise theorem" |
|
407 |
|
408 subsection{*Specialized Methods for Possibility Theorems*} |
|
409 |
|
410 ML |
|
411 {* |
377 val Nonce_supply = thm "Nonce_supply"; |
412 val Nonce_supply = thm "Nonce_supply"; |
378 |
413 |
379 (*Tactic for possibility theorems (Isar interface)*) |
414 (*Tactic for possibility theorems (Isar interface)*) |
380 fun gen_possibility_tac ss state = state |> |
415 fun gen_possibility_tac ss state = state |> |
381 REPEAT (*omit used_Says so that Nonces start from different traces!*) |
416 REPEAT (*omit used_Says so that Nonces start from different traces!*) |
384 REPEAT_FIRST (eq_assume_tac ORELSE' |
419 REPEAT_FIRST (eq_assume_tac ORELSE' |
385 resolve_tac [refl, conjI, Nonce_supply])) |
420 resolve_tac [refl, conjI, Nonce_supply])) |
386 |
421 |
387 (*Tactic for possibility theorems (ML script version)*) |
422 (*Tactic for possibility theorems (ML script version)*) |
388 fun possibility_tac state = gen_possibility_tac (simpset()) state |
423 fun possibility_tac state = gen_possibility_tac (simpset()) state |
|
424 |
|
425 (*For harder protocols (such as Recur) where we have to set up some |
|
426 nonces and keys initially*) |
|
427 fun basic_possibility_tac st = st |> |
|
428 REPEAT |
|
429 (ALLGOALS (asm_simp_tac (simpset() setSolver safe_solver)) |
|
430 THEN |
|
431 REPEAT_FIRST (resolve_tac [refl, conjI])) |
389 *} |
432 *} |
390 |
433 |
391 method_setup possibility = {* |
434 method_setup possibility = {* |
392 Method.ctxt_args (fn ctxt => |
435 Method.ctxt_args (fn ctxt => |
393 Method.METHOD (fn facts => |
436 Method.METHOD (fn facts => |
394 gen_possibility_tac (Simplifier.get_local_simpset ctxt))) *} |
437 gen_possibility_tac (Simplifier.get_local_simpset ctxt))) *} |
395 "for proving possibility theorems" |
438 "for proving possibility theorems" |
396 |
439 |
397 |
|
398 |
|
399 lemmas analz_image_freshK_simps = |
|
400 simp_thms mem_simps --{*these two allow its use with @{text "only:"}*} |
|
401 disj_comms |
|
402 image_insert [THEN sym] image_Un [THEN sym] empty_subsetI insert_subset |
|
403 analz_insert_eq Un_upper2 [THEN analz_mono, THEN subsetD] |
|
404 insert_Key_singleton |
|
405 Key_not_used insert_Key_image Un_assoc [THEN sym] |
|
406 |
|
407 ML |
|
408 {* |
|
409 val analz_image_freshK_ss = |
|
410 simpset() delsimps [image_insert, image_Un] |
|
411 delsimps [imp_disjL] (*reduces blow-up*) |
|
412 addsimps thms"analz_image_freshK_simps" |
|
413 *} |
|
414 |
|
415 end |
440 end |