packages feed

scyther-proof-0.3.0: data/examples/classic/TLS.spthy

theory TLS 
begin

section{* TLS Handshake *}

text{*
  Modeled after Paulson's TLS model in Isabelle/src/HOL/Auth/TLS.thy. Notable
  differences are:

    1. We use explicit global constants to differentiate between different
       encryptions instead of implicit typing.

    2. We abstract certificates even further to the trivial form of completely
       predistributed certificates pk(A) with their private key pk(A) for any
       agent A. The reason for this abstraction is that we need to generalize
       weak atomicity further before we can support receiving composed terms in
       a variable.

       [TODO: Remove this simplification, as weak-atomicity is now generalized.]

    3. We model session keys directly as hashes of the relevant information.
       Due to our support for composed keys, we do not need any custom
       axiomatization as Paulson did.

*}

protocol TLS {
  1. C -> S: C, nc, sid, pc
  2. C <- S: ns, sid, ps

  3. C -> S: { 'TT0', pms                  }pk(S) ,
             { 'TT1', h('TT2', ns, S, pms) }sk(C) ,
             { 'TT3', sid, h('TT4', 'PRF', pms, nc, ns),
               nc, pc, C, ns, ps, S
             } 
             h('clientKey', nc, ns, h('TT4', 'PRF', pms, nc, ns))

  4. C <- S: { 'TT3', sid, h('TT4', 'PRF', pms, nc, ns),
               nc, pc, C, ns, ps, S
             } 
             h('serverKey', nc, ns, h('TT4', 'PRF', pms, nc, ns))
}


subsection{* Secrecy Properties *}

properties (of TLS)
  C_pms_sec:  secret(C, -, pms,                          {S}) 
  C_PRF_sec:  secret(C, -, h('TT4', 'PRF', pms, nc, ns), {S})
  C_clientKey_sec:  
    secret(C, -, h('clientKey', nc, ns, h('TT4', 'PRF', pms, nc, ns)), {S})
  C_serverKey_sec:  
    secret(C, -, h('serverKey', nc, ns, h('TT4', 'PRF', pms, nc, ns)), {S})

  S_pms_sec:  secret(S, 4, pms,                          {C,S})
  S_PRF_sec:  secret(S, 4, h('TT4', 'PRF', pms, nc, ns), {C,S})

  S_clientKey_sec:  
    secret(S, 4, h('clientKey', nc, ns, h('TT4', 'PRF', pms, nc, ns)), {C,S})
  S_serverKey_sec:  
    secret(S, 4, h('serverKey', nc, ns, h('TT4', 'PRF', pms, nc, ns)), {C,S})


subsection{* Authentication Properties *}

text{*
  First, we prove two first send properties in order to simplify proof search
  for the authentication properties.
*}

property (of TLS) nc_first_send:
  premises
    "role(1) = C"
    "knows(nc#1)"
  imply
    "St(1, C_1) < Ln(nc#1)"

property (of TLS) ns_first_send:
  premises
    "role(1) = S"
    "knows(ns#1)"
  imply
    "St(1, S_2) < Ln(ns#1)"

property (of TLS) C_ni_synch:
  premises
    "role(1) = C"
    "step(1, C_4)"
    "uncompromised(C#1,S#1)"
  imply a thread 2 such that
    "  role(2) = S
    &  C#1  = C#2
    &  S#1  = S#2
    &  nc#1 = nc#2
    &  ns#1 = ns#2
    &  pc#1 = pc#2
    &  ps#1 = ps#2
    &  sid#1 = sid#2
    &  pms#1 = pms#2
    &    St(1, C_1) < St(2, S_1)
       < St(2, S_2) < St(1, C_2)
       < St(1, C_3) < St(2, S_3)
       < St(2, S_4) < St(1, C_4)
    "

property (of TLS) S_ni_synch:
  premises
    "role(2) = S"
    "step(2, S_4)"
    "uncompromised(C#2,S#2)"
  imply a thread 1 such that
    "  role(1) = C
    &  C#1  = C#2
    &  S#1  = S#2
    &  nc#1 = nc#2
    &  ns#1 = ns#2
    &  pc#1 = pc#2
    &  ps#1 = ps#2
    &  sid#1 = sid#2
    &  pms#1 = pms#2
    &    St(1, C_1) < St(2, S_1)
       < St(2, S_2) < St(1, C_2)
       < St(1, C_3) < St(2, S_3)
       < St(2, S_4) 
    "

end