(* Needham Shroeder shared key protocol

The weakness of this protocol is that if an attacker has
a session key k[Kas[], Kbs[], Na[Kbs[],c0]]
for one c0, he can have all secrets of B, since B cannot
distinguish different sessions.

 *)


pred c/1 elimVar, decompData.
pred comp/1 elimVar, decompData.

data minus/1.

fun encrypt/2.
fun host/1.

(* constants 0 and 1 *)

data c0/0.
data c1/0.

query c:secretA[i].
query c:secretB[i].
query c:secretA[c1].
query c:secretB[c1].

reduc

(* Attacker *)

c:k & c:encrypt(m,k) -> c:m;
c:x -> c:host(x);
c:x & c:y -> c:encrypt(x,y);

c:host(Kas[]);
c:host(Kbs[]);

(* key compromise 
c:k[Kas[], Kbs[], Na[host(Kbs[]),c0],c0]; *)

comp:Kas[];
comp:Kbs[];
comp:x -> comp:Na[x,c0];
comp:x & comp:y -> comp:Nb[x,y,c0];
comp:x & comp:y & comp:z -> comp:k[x,y,z,c0]; 
comp:x -> comp:host(x);
comp:x & comp:y -> comp:encrypt(x,y);
comp:x -> c:Na[x, c0];
comp:x & comp:y -> c:Nb[x,y,c0];
comp:x & comp:y & comp:z -> c:k[x,y,z,c0]; 

(* A *)

c:h -> c:(host(Kas[]), h, Na[h,i]);
c:encrypt((Na[h,i], h, key, m), Kas[]) -> c:m;
c:encrypt((Na[h,i], h, key, m), Kas[]) & c:encrypt(n, key) -> c:encrypt(minus(n), key);

c:encrypt((Na[host(Kbs[]),i], host(Kbs[]), key, m), Kas[]) -> c:encrypt(secretA[i], key);


(* B *)

c:encrypt((key, h), Kbs[]) -> c:encrypt(Nb[key,h,i], key);

c:encrypt((key, host(Kas[])), Kbs[]) -> c:encrypt(secretB[i], key);

(* S *)

c:(host(Ks1), host(Ks2), n) -> c:encrypt((n, host(Ks2), k[Ks1, Ks2, n, i], encrypt((k[Ks1, Ks2, n, i], host(Ks1)), Ks2)), Ks1).

(* EXPECTPV
RESULT goal reachable: c:secretB[c1()]
RESULT goal unreachable: c:secretA[c1()]
RESULT goal reachable: c:secretB[i]
RESULT goal reachable: c:secretA[i]
0.020s (user 0.012s + system 0.008s), max rss 8804K
END *)
