tamarin-prover-0.8.4.0: data/examples/ake/bilinear/Chen_Kudla.spthy
theory Chen_Kudla
begin
builtins: bilinear-pairing
functions: kdf/1, hp/1, h/1
section{* A variant of the Chen-Kudla protocol that uses ordered concatenation instead
addition of points *}
/*
* Protocol: Chen-Kudla (with concatenation)
* Modeler: Benedikt Schmidt
* Date: May 2012
* Source: Boyd overview identity based key exchange protocols
*
* Status: Working
*/
// Key generation center
rule KGC_Setup:
let mpk = pmult(~msk,'P')
in
[ Fr(~msk) ]
--[ KGCSetup() ]->
[ !MSK( ~msk )
, !MPK( mpk )
, Out( mpk )
]
rule KGC_request:
[ !MSK( ~msk ) ]
-->
[ !LTK( $ID, pmult(~msk, hp($ID)) ) ]
// Reveals
rule Reveal_ltk:
[ !LTK( $ID, skID ) ]
--[ LtkRev($ID) ]->
[ Out(skID) ]
rule Reveal_master_key:
[ !MSK( ~msk ) ]
--[ MskRev() ]->
[ Out( ~msk ) ]
rule Reveal_session_key:
[ !Sessk( ~ey, kdf(sek) ) ]
--[ SesskRev( ~ey ) ]->
[ Out( kdf(sek) ) ]
rule Reveal_ephemeral_key:
[ !Ephk( ~ex ) ]
--[ EphkRev( ~ex ) ]->
[ Out( ~ex ) ]
// Protocol
rule Init_1:
let X = pmult(~ex,'P')
in
[ Fr( ~ex )
]
-->
[ Init( ~ex, $A, $B )
, Out( X )
, !Ephk( ~ex )
]
rule Init_2:
let skA = pmult(~s1, hp($A))
mpk = pmult(~s2,'P')
X = pmult(~ex,'P')
sessKey = kdf( em(hp($B), mpk)^~ex, em(skA, Y), pmult(~ex,Y), $A, $B, X, Y )
in
[ Init( ~ex, $A, $B )
, !MPK( mpk )
, !LTK( $A, skA )
, In( Y )
]
--[ Accept( ~ex, $A, $B, sessKey )
, Sid( ~ex, <'Init',$A,$B,X,Y> )
// a matching session for ~ex has the following sid
, Match( ~ex, <'Resp',$B,$A,X,Y> )
]->
[ !Sessk( ~ex, sessKey ) ]
rule Resp_1:
let skB = pmult(~msk, hp($B))
mpk = pmult(~msk, 'P')
Y = pmult(~ey,'P')
// instead of multiplying the two em-terms, we concatenate them
sessKey = kdf( em(skB, X), em(hp($A), mpk)^~ey, pmult(~ey,X), $A, $B, X, Y)
in
[ Fr( ~ey )
, !LTK( $B, skB )
, !MPK( mpk )
, In( X )
]
--[ Accept( ~ey, $B, $A, sessKey )
, Sid( ~ey, <'Resp',$B,$A,X,Y> )
// a matching session for ~ey has the following sid
, Match( ~ey, <'Init',$A,$B,X,Y> )
]->
[ Out( Y )
, !Sessk( ~ey, sessKey )
, !Ephk(~ey)
]
lemma key_agreement_reachable:
exists-trace
"Ex #i #j A B SID t1 t2 k.
Accept(t1, A, B, k) @ i
& Match(t1, SID) @ i
& Accept(t2, B, A, k) @ j
& Sid(t2, SID) @ j"
lemma key_secrecy_ephemeral_no_WPFS:
/*
* If there exists a Test session whose key k is known to the
* Adversary, then...
*/
"(All #i1 #i2 test A B k.
Accept(test, A, B, k) @ i1 & K( k ) @ i2
==> (
// ... the test session must be "not clean".
// test is not clean if one of the following has happened:
//
// session-key-reveal of test thread.
(Ex #i3. SesskRev( test ) @ i3 )
// more than one KGCSetup
| (Ex #i3 #i4. KGCSetup() @ i3 & KGCSetup() @ i4 & not (#i3 = #i4))
// there is a matching session
| (Ex matching #i3 #i4 sid.
// matching's 'sid' info matches with test
( Sid ( matching, sid ) @ i3 & Match( test, sid ) @ i4)
& (
// matching's session key was revealed
(Ex #i5. SesskRev( matching ) @ i5 )
// (matching's longterm key or master key) and ephemeral key was revealed
| ( ((Ex #i5. LtkRev( B ) @ i5 ) | (Ex #i5. MskRev() @ i5 ))
& (Ex #i5. EphkRev( matching ) @ i5 ))
// both ephemeral keys are revealed, this is allowed in eCK
// the corresponding attack uses em(hp(A),mpk)^ekmatch ...
| ( (Ex #i5. EphkRev( matching ) @ i5 )
& (Ex #i5. EphkRev( test ) @ i5 )
)
// (test's longterm key or master key) and ephemeral key was revealed
| ( ((Ex #i5. LtkRev( A ) @ i5 ) | (Ex #i5. MskRev() @ i5 ))
& (Ex #i5. EphkRev( test ) @ i5 ))
)
)
// there is no matching session
| ( (not (Ex matching #i3 #i4 sid.
// matching's 'sid' info matches with test
( Sid ( matching, sid ) @ i3 & Match( test, sid ) @ i4)))
& (
// the longterm key of test.peer was revealed
(Ex #i5. LtkRev( B ) @ i5 )
// the ephemeral key of test was revealed
// in eCK, this would be allowed as long as the longterm key of test is not revealed.
| (Ex #i3. EphkRev( test ) @ i3 )
// the master key was revealed
| (Ex #i3. MskRev() @ i3)
)
)
)
)"
/*
/* For this property, there is an attack where
both ephemeral keys are revealed.
*/
lemma key_secrecy_eCK_like:
/*
* If there exists a Test session whose key k is known to the
* Adversary, then...
*/
"(All #i1 #i2 test A B k.
Accept(test, A, B, k) @ i1 & K( k ) @ i2
==> (
// ... the test session must be "not clean".
// test is not clean if one of the following has happened:
//
// session-key-reveal of test thread.
(Ex #i3. SesskRev( test ) @ i3 )
// more than one KGCSetup
| (Ex #i3 #i4. KGCSetup() @ i3 & KGCSetup() @ i4 & not (#i3 = #i4))
// there is a matching session
| (Ex matching #i3 #i4 sid.
// matching's 'sid' info matches with test
( Sid ( matching, sid ) @ i3 & Match( test, sid ) @ i4)
& (
// matching's session key was revealed
(Ex #i5. SesskRev( matching ) @ i5 )
// (matching's longterm key or master key) and ephemeral key was revealed
| ( ((Ex #i5. LtkRev( B ) @ i5 ) | (Ex #i5. MskRev() @ i5 ))
& (Ex #i5. EphkRev( matching ) @ i5 ))
// (test's longterm key or master key) and ephemeral key was revealed
| ( ((Ex #i5. LtkRev( A ) @ i5 ) | (Ex #i5. MskRev() @ i5 ))
& (Ex #i5. EphkRev( test ) @ i5 ))
)
)
// there is no matching session
| ( (not (Ex matching #i3 #i4 sid.
// matching's 'sid' info matches with test
( Sid ( matching, sid ) @ i3 & Match( test, sid ) @ i4)))
& (
// the longterm key of test.peer was revealed
(Ex #i5. LtkRev( B ) @ i5 )
// the ephemeral key of test was revealed
// in eCK, this would be allowed as long as the longterm key of test is not revealed.
| (Ex #i3. EphkRev( test ) @ i3 )
// the master key was revealed
| (Ex #i3. MskRev() @ i3)
)
)
)
)"
*/
end