packages feed

scyther-proof-0.3.1: data/examples/classic/Kerberos_V4.spthy

theory Kerberos_V4
begin

section{* The Kerberos Protocol, Version 4 *}

text{*
  Modeled after the description given by Bella [1] based on the original
  technical report [2].

  Notable differences:

    1. We do not model the timestamps and the timing properties because our
       model does not support reasoning about them yet. We model them as
       freshly generated nonces that are leaked immediately after generation.

    2. We do not model session key leakage, as our support for key compromise
       properties is not ready yet.

    3. We provide more general authentication and secrecy properties, as we do
       not assume a priory the uncompromisedness of the ticket granting server.
       Furthermore, the authentication propertis are more fine-grained due to
       our more precise execution model.

    4. We use explicit global constants instead of implicit typing to identify
       the different encryptions.

    5. We use the abbreviations: C for Client, A for authenticator, G for
       ticket granting server, S for server.


[1] Bella, Giampaolo and Paulson, Lawrence C., "Kerberos Version 4: Inductive
    Analysis of the Secrecy Goals", in ESORICS, 1998, pp. 361-375.

[2] Miller, S. P. and Neuman, B. C. and Schiller, J. I. and Saltzer, J. H.,
    "Kerberos Authentication and Authorization System", in Project Athena Technical
    Plan, 1987, pp. 1-36.
*}

protocol Kerberos
{
  1_leak. C -> : Tc1
  1. C -> A: C,G,Tc1

  2_leak. A -> : Ta
  2.   <- A: A, {'21', AuthKey, G, Ta, {'22', C, G, AuthKey, Ta}k(A,G) }k(C,A)
     C <-  : A, {'21', AuthKey, G, Ta, AuthTicket                      }k(C,A)
  
  3_leak. C -> : Tc2
  3. C ->  : A, AuthTicket,                      {'3', C, Tc2}AuthKey, S
       -> G: A, {'22', C, G, AuthKey, Ta}k(A,G), {'3', C, Tc2}AuthKey, S

  4_leak. G -> : Tg
  4.   <- G: {'41', ServKey, S, Tg, {'42', C, S, ServKey, Tg}k(G,S) }AuthKey
     C <-  : {'41', ServKey, S, Tg, ServTicket                      }AuthKey


  5_leak. C -> : Tc3
  5. C ->  : G, ServTicket,                      {'5', C, Tc3}ServKey
       -> S: G, {'42', C, S, ServKey, Tg}k(G,S), {'5', C, Tc3}ServKey     

  6. C <- S: {'6', Tc3}ServKey
}

// The type inference heuristic is wrong for the type of ServTicket@C
// Therefore, we had to modify its output to the following type.
property (of Kerberos) Kerberos_typing:
  "// client variables
   A@C          :: Known(C_2)
   AuthKey@C    :: Known(C_2) | AuthKey@A
   ServKey@C    :: Known(C_4) | ServKey@G
   Ta@C         :: Known(C_2) | Ta@A
   Tg@C         :: Known(C_4) | Tg@G
   AuthTicket@C :: 
     Known(C_2) | {'22', Known(C_2), Agent, AuthKey@A, Ta@A}k(Agent, Agent)
   ServTicket@C :: Known(C_4) | {'42', Known(C_4), Agent, ServKey@G, Tg@G}k(Agent, Agent)

   // authenticator variables
   C@A   :: Known(A_1)
   G@A   :: Known(A_1)
   Tc1@A :: Known(A_1)

   // ticket granting server variables
   A@G       :: Known(G_3)
   C@G       :: Known(G_3) | Agent
   S@G       :: Known(G_3)
   AuthKey@G :: Known(G_3) | AuthKey@A
   Ta@G      :: Known(G_3) | Ta@A
   Tc2@G     :: Known(G_3) | Tc2@C

   // server variables
   C@S       :: Known(S_5) | Agent
   G@S       :: Known(S_5)
   ServKey@S :: Known(S_5) | ServKey@G
   Tg@S      :: Known(S_5) | Tg@G
   Tc3@S     :: Known(S_5) | Tc3@C
  "


subsection{* Secrecy Properties *}

properties (of Kerberos)
  A_AuthKey_secret: secret(A, -, AuthKey, {C,A,G})
  C_AuthKey_secret: secret(C, 2, AuthKey, {C,A,G})
  G_AuthKey_secret: secret(G, 3, AuthKey, {C,A,G})

  G_ServKey_sec: secret(G, -, ServKey, {C,A,G,S})
  C_ServKey_sec: secret(C, 4, ServKey, {C,A,G,S})
  
  // no secrecy for ServKey at server S because it cannot verify the
  // uncompromisedness of A


subsection{* Authentication Properties *}

// client
property (of Kerberos) C_auth:
  premises
    "role(1) = C"
    "uncompromised(C#1, A#1, G#1, S#1)"
    "step(1, C_6)"
  imply threads 2, 3, 4 such that
    "
     // consequence from exchange with authenticator
     role(2) = A &
     A#1  = A#2 & 
     C#1  = C#2 & 
     G#1  = G#2 &
     Ta#1 = Ta#2 &
     AuthKey#1 = AuthKey#2 & 
     
     // consequence from exchange with ticket granting server
     role(3) = G &
     A#1  = A#3 & 
     C#1  = C#3 & 
     G#1  = G#3 &
     S#1  = S#3 &
     Tg#1 = Tg#3 &
     AuthKey#1 = AuthKey#3 &
     ServKey#1 = ServKey#3 &

     // consequence from exchange with server
     role(4) = S &
     C#1 = C#4 & 
     G#1 = G#4 &
     S#1 = S#4 &
     Tc3#1 = Tc3#4 &
     ServKey#1 = ServKey#4 
     "

// ticket granting server
property (of Kerberos) G_auth:
  premises
    "role(3) = G"
    "uncompromised(C#3, A#3, G#3)"
    "step(3, G_3)"
  imply threads 1, 2 such that
    "
     // consequence from receiving from client
     role(1) = C &
     A#1   = A#3 & 
     C#1   = C#3 & 
     G#1   = G#3 &
     Tc2#1 = Tc2#3 &
     AuthKey#1 = AuthKey#3 &
     // no agreement on ServKey and S as they are not guaranteed to have been
     // received by the client yet.

     // consequence of client receiving from authenticator
     role(2) = A &
     A#1 = A#2 & 
     C#1 = C#2 & 
     G#1 = G#2 &
     AuthKey#1 = AuthKey#2
    "

/*
text{*
  Here we can only formulate a weaker authentication property because the
  uncompromisedness of the authenticator cannot be verified directly by the server.
  What we can prove is under the assumption that we got our ServKey from
  some ticket granting server and this server was talking to an uncompromised
  authenticator, then we have sort of an authentication.
*}

property (of Kerberos) S_auth:
  premises
    "role(4) = S"
    "uncompromised(C#4, S#4, G#4)"
    "step(4, S_5)"

    "role(3) = G"
    "uncompromised(A#3)"
    "ServKey#4 = ServKey#3"
  imply threads 1, 2 such that
    "
     // consequence from exchange with authenticator
     role(1) = C &
     role(2) = A &
     A#1 = A#2 & 
     C#1 = C#2 & 
     G#1 = G#2 &
     AuthKey#1 = AuthKey#2 & 
     
     // consequence from exchange with ticket granting server
     A#1 = A#3 & 
     C#1 = C#3 & 
     G#1 = G#3 &
     S#1 = S#3 &
     AuthKey#1 = AuthKey#3 &
     ServKey#1 = ServKey#3 &

     // consequence from exchange with client
     C#1 = C#4 & 
     G#1 = G#4 &
     S#1 = S#4 &
     t#1 = t#4 &
     ServKey#1 = ServKey#4 &

     // ordering consequences
     St(1, C_1) < St(2, A_1) <
     St(2, A_2) < St(1, C_2) <
     St(1, C_3) < St(3, T_3) <
     St(3, T_4) < St(1, C_4) <
     St(1, C_5) < St(4, S_5)
    "
*/


end