hash h1
hash h2
abstract ok : message
abstract error : message
name key1 : index -> message
name key2 : index -> message
name k : index -> message
name r1 : index -> message
name k1init : index -> message
name k2init : index -> message
mutable kT(i:index) : message = <k1init(i),k2init(i)>
mutable kR(i:index) : message = <k1init(i),k2init(i)>
channel cT
channel cR
(* i = tag's identity, j = tag's session for identity i *)
process tag(i:index,j:index) =
in(cR, xr1);
out(cT, h1(fst(kT(i)) XOR xr1 XOR k(i), key1(i)));
in(cR, xh2);
if xh2 = h2(snd(kT(i)), key2(i)) then
kT(i) := < fst(kT(i)) XOR h2(snd(kT(i)), key2(i)),
snd(kT(i)) XOR h1(fst(kT(i)) XOR xr1 XOR k(i), key1(i)) >;
out(cT, ok)
else
out(cT, error)
(* jj = generic reader's session *)
process reader(jj:index) =
out(cR, r1(jj));
in(cT, xh1);
try find ii such that xh1 = h1(fst(kR(ii)) XOR r1(jj) XOR k(ii), key1(ii)) in
let m = h2(snd(kR(ii)),key2(ii)) in
kR(ii) := < fst(kR(ii)) XOR h2(snd(kR(ii)), key2(ii)),
snd(kR(ii)) XOR h1(fst(kR(ii)) XOR r1(jj) XOR k(ii), key1(ii)) >;
out(cT, m)
else
out(cT, error)
system ((!_jj R: reader(jj)) | (!_i !_j T: tag(i,j))).
Typed-check process:
null
Added action dependencies lemmas:
System after processing:
null
System Empty registered with actions (init).
[warning>Loaded "Prelude.sp".
<]global axiom namelength_key1 {'P:system} @system:(set:'P; equiv:None) :
[forall (i:index), len (key1 i) = namelength_message]
global axiom namelength_key2 {'P:system} @system:(set:'P; equiv:None) :
[forall (i:index), len (key2 i) = namelength_message]
global axiom namelength_k {'P:system} @system:(set:'P; equiv:None) :
[forall (i:index), len (k i) = namelength_message]
global axiom namelength_r1 {'P:system} @system:(set:'P; equiv:None) :
[forall (i:index), len (r1 i) = namelength_message]
global axiom namelength_k1init {'P:system} @system:(set:'P; equiv:None) :
[forall (i:index), len (k1init i) = namelength_message]
global axiom namelength_k2init {'P:system} @system:(set:'P; equiv:None) :
[forall (i:index), len (k2init i) = namelength_message]
process tag (i,j:index) =
in(cR,xr1);
out(cT,h1 (xor (xor (fst (kT i@τ)) xr1) (k i), key1 i));
in(cR,xh2);
if xh2 = h2 (snd (kT i@τ), key2 i) then
kT(i) :=
<xor (fst (kT i@τ)) (h2 (snd (kT i@τ), key2 i)),
xor (snd (kT i@τ)) (h1 (xor (xor (fst (kT i@τ)) xr1) (k i), key1 i))>;
out(cT,ok);
null
else
out(cT,error); null
process reader (jj:index) =
out(cR,r1 jj);
in(cT,xh1);
find (ii) such that xh1 =
h1
(xor (xor (fst (kR ii@τ)) (r1 jj)) (k ii), key1 ii) in
let m : message = h2 (snd (kR ii@τ), key2 ii) in
kR(ii) :=
<xor (fst (kR ii@τ)) (h2 (snd (kR ii@τ), key2 ii)),
xor
(snd (kR ii@τ))
(h1 (xor (xor (fst (kR ii@τ)) (r1 jj)) (k ii), key1 ii))>;
out(cT,m);
null
else
out(cT,error); null
Typed-check process:
( !_jj( R: reader jj) ) | !_i( !_j( T: tag i j))
Added action dependencies lemmas:
axiom mutex_T2_T1 {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (i,j:index), not happens(T2(i, j)) || not happens(T1(i, j))
axiom mutex_T1_T2 {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (i,j:index), not happens(T1(i, j)) || not happens(T2(i, j))
axiom depends_T_T2 {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (i,j:index), happens(T2(i, j)) => T(i, j) < T2(i, j)
axiom depends_T_T1 {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (i,j:index), happens(T1(i, j)) => T(i, j) < T1(i, j)
axiom mutex_R2_R1 {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (jj,ii:index), not happens(R2(jj)) || not happens(R1(jj, ii))
axiom mutex_R1_R2 {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (jj,ii:index), not happens(R1(jj, ii)) || not happens(R2(jj))
axiom depends_R_R2 {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (jj:index), happens(R2(jj)) => R(jj) < R2(jj)
axiom depends_R_R1 {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (jj,ii:index), happens(R1(jj, ii)) => R(jj) < R1(jj, ii)
axiom depends_init_T2 {'P:system[like default]} @system:(set:'P; equiv:None)
: forall (i,j:index), happens(T2(i, j)) => init < T2(i, j)
axiom depends_init_T1 {'P:system[like default]} @system:(set:'P; equiv:None)
: forall (i,j:index), happens(T1(i, j)) => init < T1(i, j)
axiom depends_init_T {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (i,j:index), happens(T(i, j)) => init < T(i, j)
axiom depends_init_R2 {'P:system[like default]} @system:(set:'P; equiv:None)
: forall (jj:index), happens(R2(jj)) => init < R2(jj)
axiom depends_init_R1 {'P:system[like default]} @system:(set:'P; equiv:None)
: forall (jj,ii:index), happens(R1(jj, ii)) => init < R1(jj, ii)
axiom depends_init_R {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (jj:index), happens(R(jj)) => init < R(jj)
System after processing:
( !_jj(
R: out(cR,r1 jj);
in(cT,xh1);
find (ii) such that xh1 =
h1
(xor (xor (fst (kR ii@τ)) (r1 jj)) (k ii),
key1 ii) in
let m : message = h2 (snd (kR ii@τ), key2 ii) in
kR(ii) :=
<xor (fst (kR ii@τ)) (h2 (snd (kR ii@τ), key2 ii)),
xor
(snd (kR ii@τ))
(h1 (xor (xor (fst (kR ii@τ)) (r1 jj)) (k ii), key1 ii))>;
R1: out(cT,m jj ii@τ);
null
else
R2: out(cT,error); null) ) |
!_i(
!_j(
in(cR,xr1);
T: out(cT,h1 (xor (xor (fst (kT i@τ)) xr1) (k i), key1 i));
in(cR,xh2);
if xh2 = h2 (snd (kT i@τ), key2 i) then
kT(i) :=
<xor (fst (kT i@τ)) (h2 (snd (kT i@τ), key2 i)),
xor
(snd (kT i@τ))
(h1 (xor (xor (fst (kT i@τ)) (input@T(i, j))) (k i), key1 i))>;
T1: out(cT,ok);
null
else
T2: out(cT,error); null))
System Empty registered with actions (init).
System default registered with actions (init,R,R1,R2,T,T1,T2).
YPLRK05
T. van Deursen and S. Radomirović, ‘Attacks on RFID Protocols’,
Cryptology ePrint Archive, vol. 2008, no. 310, pp. 1–56, Aug. 2009.
The reader and tag share secrets k, k1, k2. The reader initiates the
protocol by challenging the tag with a nonce r1. The tag responds with
h(k1 XOR r1 XOR k). The reader then replies with h(k2) and both tag and
reader update secrets k1 and k2.
R -> T : r1 T -> R : h(kT1+r1+k) kT1 := kT1+h(kT2) kT2 :=
kT2+h(kT1+r1+k) R -> T : h(kR2) kR1 := kR1+h(kR2) kR2 :=
kR2+h(kR1+r1+k)
COMMENTS - In this model we use 2 different keyed hash functions,
instead of a single (not keyed) hash function as in the
specification.
HELPING LEMMAS - no update
SECURITY PROPERTIES - authentication
******************************************************************************