Example (7) → ( ν sk A )( ν sk B ) ( ν k ) c � pencrypt(sign( k , sk A ) , pk( sk B )) � . ( c ( x ) . let s = sdecrypt( x , k ) in 0 c ( y ) . let y ′ = pdecrypt( y , sk B ) in | let k = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ) � | ! c ( x pk B ) . . . . | ! c ( y ) . . . . ) Bruno Blanchet (INRIA) ProVerif September 2013 24 / 114
Example (8) ≡ ( ν sk A )( ν sk B )( ν k ) c � pencrypt(sign( k , sk A ) , pk( sk B )) � . ( c ( x ) . let s = sdecrypt( x , k ) in 0 c ( y ) . let y ′ = pdecrypt( y , sk B ) in | let k ′ = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ′ ) � ) | ! c ( x pk B ) . . . . | ! c ( y ) . . . . ) Bruno Blanchet (INRIA) ProVerif September 2013 25 / 114
Example (9) → ∗ ( ν sk A )( ν sk B )( ν k ) ( c ( x ) . let s = sdecrypt( x , k ) in 0 let y ′ = pdecrypt(pencrypt(sign( k , sk A ) , pk( sk B )) , sk B ) in | let k ′ = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ′ ) � | ! c ( x pk B ) . . . . | ! c ( y ) . . . . ) Bruno Blanchet (INRIA) ProVerif September 2013 26 / 114
Example (10) → ∗ ( ν sk A )( ν sk B )( ν k ) ( c ( x ) . let s = sdecrypt( x , k ) in 0 | c � sencrypt(s , k ) � | ! c ( x pk B ) . . . . | ! c ( y ) . . . . ) Bruno Blanchet (INRIA) ProVerif September 2013 27 / 114
Example (11) → ∗ ( ν sk A )( ν sk B )( ν k ) ( let s = sdecrypt(sencrypt(s , k ) , k ) in 0 | ! c ( x pk B ) . . . . | ! c ( y ) . . . . ) Bruno Blanchet (INRIA) ProVerif September 2013 28 / 114
Another presentation of the semantics Semantic configurations are E , P where E is a set of names P is a multiset of processes Intuitively, E , P where E = { a 1 , . . . , a n } and P = { P 1 , . . . , P m } corresponds to ( ν a 1 ) . . . ( ν a n )( P 1 | . . . | P m ) Initial configuration for P : fn( P ) , { P } . Bruno Blanchet (INRIA) ProVerif September 2013 29 / 114
Another presentation of the semantics: reduction relation E , P ∪ { 0 } → E , P (Red Nil) E , P ∪ { ! P } → E , P ∪ { P , ! P } (Red Repl) E , P ∪ { P | Q } → E , P ∪ { P , Q } (Red Par) E , P ∪ { ( ν a ) P } → E ∪ { a ′ } , P ∪ { P { a ′ / a } } (Red Res) where a ′ / ∈ E . E , P ∪ { N � M � . Q , N ( x ) . P } → E , P ∪ { Q , P { M / x } } (Red I/O) E , P ∪ { let x = g ( M 1 , . . . , M n ) in P else Q } → E , P ∪ { P { M ′ / x } } if g ( M 1 , . . . , M n ) → M ′ (Red Destr 1) E , P ∪ { let x = g ( M 1 , . . . , M n ) in P else Q } → E , P ∪ { Q } if there exists no M ′ such that g ( M 1 , . . . , M n ) → M ′ (Red Destr 2) Bruno Blanchet (INRIA) ProVerif September 2013 30 / 114
Example { c } , { c ( xpk A ) . c ( xpk B ) . c � xpk B � | ( ν sk A )( ν sk B ) let pk A = pk( sk A ) in let pk B = pk( sk B ) in c � pk A � . c � pk B � . ( ! c ( x pk B ) . ( ν k ) c � pencrypt(sign( k , sk A ) , x pk B ) � . c ( x ) . let s = sdecrypt( x , k ) in 0 ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in | let k = checksign( y ′ , pk A ) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 31 / 114
Example (2) → { c } , { c ( xpk A ) . c ( xpk B ) . c � xpk B � , ( ν sk A )( ν sk B ) let pk A = pk( sk A ) in let pk B = pk( sk B ) in c � pk A � . c � pk B � . ( ! c ( x pk B ) . ( ν k ) c � pencrypt(sign( k , sk A ) , x pk B ) � . c ( x ) . let s = sdecrypt( x , k ) in 0 ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in | let k = checksign( y ′ , pk A ) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 32 / 114
Example (2) → { c } , { c ( xpk A ) . c ( xpk B ) . c � xpk B � , ( ν sk A )( ν sk B ) let pk A = pk( sk A ) in let pk B = pk( sk B ) in c � pk A � . c � pk B � . ( ! c ( x pk B ) . ( ν k ) c � pencrypt(sign( k , sk A ) , x pk B ) � . c ( x ) . let s = sdecrypt( x , k ) in 0 ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in | let k = checksign( y ′ , pk A ) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 32 / 114
Example (3) → ∗ { c , sk A , sk B } , { c ( xpk A ) . c ( xpk B ) . c � xpk B � , let pk A = pk( sk A ) in let pk B = pk( sk B ) in c � pk A � . c � pk B � . ( ! c ( x pk B ) . ( ν k ) c � pencrypt(sign( k , sk A ) , x pk B ) � . c ( x ) . let s = sdecrypt( x , k ) in 0 ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in | let k = checksign( y ′ , pk A ) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 33 / 114
Example (3) → ∗ { c , sk A , sk B } , { c ( xpk A ) . c ( xpk B ) . c � xpk B � , let pk A = pk( sk A ) in let pk B = pk( sk B ) in c � pk A � . c � pk B � . ( ! c ( x pk B ) . ( ν k ) c � pencrypt(sign( k , sk A ) , x pk B ) � . c ( x ) . let s = sdecrypt( x , k ) in 0 ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in | let k = checksign( y ′ , pk A ) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 33 / 114
Example (4) → ∗ { c , sk A , sk B } , { c ( xpk A ) . c ( xpk B ) . c � xpk B � , c � pk( sk A ) � . c � pk( sk B ) � . ( ! c ( x pk B ) . ( ν k ) c � pencrypt(sign( k , sk A ) , x pk B ) � . c ( x ) . let s = sdecrypt( x , k ) in 0 ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in | let k = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 34 / 114
Example (4) → ∗ { c , sk A , sk B } , { c ( xpk A ) . c ( xpk B ) . c � xpk B � , c � pk( sk A ) � . c � pk( sk B ) � . ( ! c ( x pk B ) . ( ν k ) c � pencrypt(sign( k , sk A ) , x pk B ) � . c ( x ) . let s = sdecrypt( x , k ) in 0 ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in | let k = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 34 / 114
Example (5) → ∗ { c , sk A , sk B } , { c � pk( sk B ) � , ! c ( x pk B ) . ( ν k ) c � pencrypt(sign( k , sk A ) , x pk B ) � . ( c ( x ) . let s = sdecrypt( x , k ) in 0 ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in | let k = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 35 / 114
Example (5) → ∗ { c , sk A , sk B } , { c � pk( sk B ) � , ! c ( x pk B ) . ( ν k ) c � pencrypt(sign( k , sk A ) , x pk B ) � . ( c ( x ) . let s = sdecrypt( x , k ) in 0 ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in | let k = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 35 / 114
Example (6) → { c , sk A , sk B } , { c � pk( sk B ) � , ! c ( x pk B ) . ( ν k ) c � pencrypt(sign( k , sk A ) , x pk B ) � . c ( x ) . let s = sdecrypt( x , k ) in 0 , ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in let k = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 36 / 114
Example (6) → { c , sk A , sk B } , { c � pk( sk B ) � , ! c ( x pk B ) . ( ν k ) c � pencrypt(sign( k , sk A ) , x pk B ) � . c ( x ) . let s = sdecrypt( x , k ) in 0 , ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in let k = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 36 / 114
Example (7) → { c , sk A , sk B } , { c � pk( sk B ) � , c ( x pk B ) . ( ν k ) c � pencrypt(sign( k , sk A ) , x pk B ) � . c ( x ) . let s = sdecrypt( x , k ) in 0 , ! c ( x pk B ) . . . . , ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in let k = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 37 / 114
Example (7) → { c , sk A , sk B } , { c � pk( sk B ) � , c ( x pk B ) . ( ν k ) c � pencrypt(sign( k , sk A ) , x pk B ) � . c ( x ) . let s = sdecrypt( x , k ) in 0 , ! c ( x pk B ) . . . . , ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in let k = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 37 / 114
Example (8) → { c , sk A , sk B } , { ( ν k ) c � pencrypt(sign( k , sk A ) , pk( sk B )) � . c ( x ) . let s = sdecrypt( x , k ) in 0 , ! c ( x pk B ) . . . . , ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in let k = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 38 / 114
Example (8) → { c , sk A , sk B } , { ( ν k ) c � pencrypt(sign( k , sk A ) , pk( sk B )) � . c ( x ) . let s = sdecrypt( x , k ) in 0 , ! c ( x pk B ) . . . . , ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in let k = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 38 / 114
Example (9) → { c , sk A , sk B , k ′ } , c � pencrypt(sign( k ′ , sk A ) , pk( sk B )) � . { c ( x ) . let s = sdecrypt( x , k ′ ) in 0 , ! c ( x pk B ) . . . . , ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in let k = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 39 / 114
Example (9) → { c , sk A , sk B , k ′ } , c � pencrypt(sign( k ′ , sk A ) , pk( sk B )) � . { c ( x ) . let s = sdecrypt( x , k ′ ) in 0 , ! c ( x pk B ) . . . . , ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in let k = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ) � ) } Bruno Blanchet (INRIA) ProVerif September 2013 39 / 114
Example (10) → ∗ { c , sk A , sk B , k ′ } , c ( x ) . let s = sdecrypt( x , k ′ ) in 0 , { ! c ( x pk B ) . . . . , let y ′ = pdecrypt(pencrypt(sign( k ′ , sk A ) , pk( sk B )) , sk B ) in let k = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ) � ) ! c ( y ) . . . . } Bruno Blanchet (INRIA) ProVerif September 2013 40 / 114
Example (10) → ∗ { c , sk A , sk B , k ′ } , c ( x ) . let s = sdecrypt( x , k ′ ) in 0 , { ! c ( x pk B ) . . . . , let y ′ = pdecrypt(pencrypt(sign( k ′ , sk A ) , pk( sk B )) , sk B ) in let k = checksign( y ′ , pk( sk A )) in c � sencrypt(s , k ) � ) ! c ( y ) . . . . } Bruno Blanchet (INRIA) ProVerif September 2013 40 / 114
Example (11) → ∗ { c , sk A , sk B , k ′ } , c ( x ) . let s = sdecrypt( x , k ′ ) in 0 , { ! c ( x pk B ) . . . . , c � sencrypt(s , k ′ ) � ) ! c ( y ) . . . . } Bruno Blanchet (INRIA) ProVerif September 2013 41 / 114
Example (11) → ∗ { c , sk A , sk B , k ′ } , c ( x ) . let s = sdecrypt( x , k ′ ) in 0 , { ! c ( x pk B ) . . . . , c � sencrypt(s , k ′ ) � ) ! c ( y ) . . . . } Bruno Blanchet (INRIA) ProVerif September 2013 41 / 114
Example (12) → { c , sk A , sk B , k ′ } , let s = sdecrypt(sencrypt(s , k ′ ) , k ′ ) in 0 , { ! c ( x pk B ) . . . . , ! c ( y ) . . . . } Bruno Blanchet (INRIA) ProVerif September 2013 42 / 114
Example (12) → { c , sk A , sk B , k ′ } , let s = sdecrypt(sencrypt(s , k ′ ) , k ′ ) in 0 , { ! c ( x pk B ) . . . . , ! c ( y ) . . . . } Bruno Blanchet (INRIA) ProVerif September 2013 42 / 114
Comparison between the two semantics The first semantics is more standard (comes from the original semantics of the pi calculus) makes it easier to add a context around an existing process (see definition of process equivalence) The second semantics directs the reduction more precisely makes a minimal use of renaming (for restrictions only) Except when mentioned explicitly, I will rely on the second semantics. Bruno Blanchet (INRIA) ProVerif September 2013 43 / 114
Adversary The protocol is executed in parallel with an adversary. The adversary can be any process. S = finite set of names (initial knowledge of the adversary). Definition The closed process Q is an S -adversary ⇔ fn( Q ) ⊆ S . Bruno Blanchet (INRIA) ProVerif September 2013 44 / 114
Secrecy Intuitive definition The secret M cannot be output on a public channel Definition A trace T = E 0 , P 0 → ∗ E ′ , P ′ outputs M if and only if T contains a reduction E , P ∪ { c � M � . Q , c ( x ) . P } → E , P ∪ { Q , P { M / x } } for some E , P , x , P , Q , and c ∈ S . Definition The closed process P preserves the secrecy of M from S ⇔ ∀ S -adversary Q , ∀T = fn( P ) ∪ S , { P , Q } → ∗ E ′ , P ′ , T does not output M . Bruno Blanchet (INRIA) ProVerif September 2013 45 / 114
Several variants of the spi calculus Presented variant [Abadi, Blanchet, POPL’02 and JACM’05] The spi-calculus [Abadi, Gordon, I&C, 1999] The applied pi calculus [Abadi, Fournet, POPL’01] Very powerful, thanks to equational theories A calculus for asymmetric communication [Abadi, Blanchet, FoSSaCS’01 and TCS’03] Bruno Blanchet (INRIA) ProVerif September 2013 46 / 114
Overview 1. A variant of the spi-calculus 2. Intuitive presentation of the Horn clause representation 3. The resolution algorithm 4. Formal translation from the spi-calculus. 5. Extension to correspondences Bruno Blanchet (INRIA) ProVerif September 2013 47 / 114
ProVerif ProVerif is a verifier for cryptographic protocols Fully automatic For an unbounded number of sessions and an unbounded message size Undecidable problem ⇒ need for abstractions Handles a wide range of cryptographic primitives, defined by rewrite rules or equations Proves various security properties: secrecy, correspondences, some equivalences Does not always terminate and is not complete. In practice: Efficient: small examples verified in less than 0.1 s; complex ones in a few minutes. Very precise: no false attack in our tests for secrecy and authentication. Bruno Blanchet (INRIA) ProVerif September 2013 48 / 114
Our solution Two ideas (extending [Weidenbach, CADE’99]): a simple abstract representation of protocols, by a set of Horn clauses; an efficient resolution algorithm to find which facts can be derived from these clauses. Using these ideas, we can prove secrecy properties of protocols, or exhibit attacks showing why a message is not secret. Bruno Blanchet (INRIA) ProVerif September 2013 49 / 114
Protocol representation Messages � terms M ::= x | f ( M 1 , . . . , M n ) | k [ M 1 , . . . , M n ] pencrypt( c 0 , pk( sk A )). Properties � facts F ::= attacker( M ). Protocol, attacker � Horn clauses F 1 ∧ . . . ∧ F n ⇒ F attacker( m ) ∧ attacker( pk ) ⇒ attacker(pencrypt( m , pk )). Bruno Blanchet (INRIA) ProVerif September 2013 50 / 114
Example - Cryptographic primitives Public-key encryption: Encryption pencrypt( m , pk ). attacker( m ) ∧ attacker( pk ) ⇒ attacker(pencrypt( m , pk )) Public key generation pk( sk ). (builds a public key from a secret key) attacker( sk ) ⇒ attacker(pk( sk )) Decryption pdecrypt(pencrypt( m , pk( sk )) , sk ) → m . attacker(pencrypt( m , pk( sk ))) ∧ attacker( sk ) ⇒ attacker( m ) Bruno Blanchet (INRIA) ProVerif September 2013 51 / 114
General treatment of primitives Constructors f ( M 1 , . . . , M n ) attacker( x 1 ) ∧ . . . ∧ attacker( x n ) ⇒ attacker( f ( x 1 , . . . , x n )) Destructors g ( M 1 , . . . , M n ) → M attacker( M 1 ) ∧ . . . ∧ attacker( M n ) ⇒ attacker( M ) (There may be several rewrite rules defining a function.) Exercise Give clauses for shared-key encryption and signatures Bruno Blanchet (INRIA) ProVerif September 2013 52 / 114
Initial knowledge Clauses that represent the initial knowledge of the adversary: attacker( M ) if the adversary knows M . Example For the Denning-Sacco protocol: attacker(pk( sk A )) attacker(pk( sk B )) Bruno Blanchet (INRIA) ProVerif September 2013 53 / 114
Names Normally, fresh names are created each time the protocol is run. Here, we only distinguish two names when they are created after receiving different messages. Each name k becomes a function of the messages previously received: k [ M 1 , . . . , M n ] . (Skolemisation) These functions can only be applied by the principal that creates the name, not by the attacker. The attacker can create his own fresh names: attacker( b [ ]). Bruno Blanchet (INRIA) ProVerif September 2013 54 / 114
Denning-Sacco protocol A → B : {{ k } sk A } pk B k fresh A talks to any principal represented by its public key pk( x ). A sends to it the message {{ k } sk A } pk( x ) . attacker(pk( x )) ⇒ attacker(pencrypt(sign( k [pk( x )] , sk A [ ]) , pk( x ))). B → A : { s } k B has received a message {{ y } sk A } pk B . B sends { s } y . attacker(pencrypt(sign( y , sk A [ ]) , pk( sk B [ ]))) ⇒ attacker(sencrypt(s , y )). Bruno Blanchet (INRIA) ProVerif September 2013 55 / 114
General coding of a protocol If a principal A has received the messages M 1 , . . . , M n and sends the message M , attacker( M 1 ) ∧ . . . ∧ attacker( M n ) ⇒ attacker( M ) . Exercise Give Horn clauses for the Needham-Schroeder public key protocol: Message 1. A → B { N a , A } pk B N a fresh B → A { N a , N b } pk A Message 2. N b fresh Message 3. A → B { N b } pk B Bruno Blanchet (INRIA) ProVerif September 2013 56 / 114
Approximations The freshness of nonces is partially modeled. The number of times a message appears is ignored, only the fact that is has appeared is taken into account. The state of the principals is not fully modeled. These approximations are keys for an efficient verification. Solve the state space explosion problem. No limit on the number of runs of the protocols. ⇒ essential for the certification of protocols. Bruno Blanchet (INRIA) ProVerif September 2013 57 / 114
Approximations: a more formal view We can show formally by abstract interpretation that, with respect to the multiset rewriting model, the only approximation is that the number of repetitions of actions is ignored [Blanchet, IPL, 2005]. Multiset rewriting ⇔ linear logic After approximation: classical logic The modeling of names by skolemisation does not introduce an approximation in classical logic. Typical situation in which the proof fails: a protocol first needs to keep some data secret, and later reveals it. Bruno Blanchet (INRIA) ProVerif September 2013 58 / 114
Secrecy Secrecy criterion If attacker( M ) cannot be derived from the clauses, then M is secret. The term M cannot be built by an attacker. The resolution algorithm will determine whether a given fact can be derived from the clauses. Bruno Blanchet (INRIA) ProVerif September 2013 59 / 114
Overview 1. A variant of the spi-calculus 2. Intuitive presentation of the Horn clause representation 3. The resolution algorithm 4. Formal translation from the spi-calculus. 5. Extension to correspondences Bruno Blanchet (INRIA) ProVerif September 2013 60 / 114
Which resolution algorithm A standard Prolog system would not terminate: attacker(sencrypt( x , y )) ∧ attacker( y ) ⇒ attacker( x ) generates bigger and bigger facts by SLD-resolution. We need a different resolution strategy. Bruno Blanchet (INRIA) ProVerif September 2013 61 / 114
Saturation Completion of the clause base, by resolution with free selection. Selection function sel ( F 1 ∧ . . . ∧ F n ⇒ F ) ∈ { F 1 , . . . , F n , F } . F if ∀ i ∈ { 1 , . . . , n } , F i = attacker( x ) sel ( F 1 ∧ . . . ∧ F n ⇒ F ) = F i different from attacker( x ), of maximal size, otherwise Bruno Blanchet (INRIA) ProVerif September 2013 62 / 114
Saturation (2) R ′ = F ′ 1 ∧ . . . ∧ F ′ n ′ ⇒ F ′ R = F 1 ∧ . . . ∧ F n ⇒ F σ F 1 ∧ . . . ∧ σ F n ∧ σ F ′ 2 ∧ . . . ∧ σ F ′ n ′ ⇒ σ F ′ where σ is the most general unifier of F and F ′ 1 , where sel ( R ) = F , and sel ( R ′ ) = F ′ 1 . Starting from an initial set of clauses R 0 , perform this resolution step until a fixed point is reached, eliminating subsumed clauses: H ⇒ C subsumes H ′ ⇒ C ′ when there exists σ such that σ H ⊆ H ′ (multiset inclusion) and σ C = C ′ . saturate ( R 0 ) is the set of obtained clauses R such that sel ( R ) is the conclusion of R . Bruno Blanchet (INRIA) ProVerif September 2013 63 / 114
Saturation (3) Example of a step: attacker( x ) ∧ attacker( y ) ⇒ attacker(pencrypt( x , y )) attacker(pencrypt(sign( z , sk A [ ]) , pk( sk B [ ]))) ⇒ attacker(sencrypt(s , z )) attacker(sign( z , sk A [ ])) ∧ attacker(pk( sk B [ ])) ⇒ attacker(sencrypt(s , z )) Theorem The clauses obtained after saturation saturate ( R 0 ) derive the same facts as the initial clauses R 0 . Bruno Blanchet (INRIA) ProVerif September 2013 64 / 114
Why it works The facts attacker( x ) unify with all facts attacker( M ). If we allow resolution on facts attacker( x ), we will create many clauses. The choice of the selection function implies that we avoid performing resolution upon attacker( x ). ⇒ This is key to obtaining termination in most cases. Bruno Blanchet (INRIA) ProVerif September 2013 65 / 114
Derivation Let F be a closed fact. 1 Add the clause F ⇒ bad: R ′ 0 = R 0 ∪ { F ⇒ bad } . 2 Let deriv R 0 ( F ) be true if and only if saturate ( R ′ 0 ) contains a clause H ⇒ bad for some H . If F is derivable from R 0 then bad is derivable from R ′ 0 then bad is derivable from saturate ( R ′ 0 ) (previous theorem) then deriv R 0 ( F ) is true. If deriv R 0 ( F ) is false, then F is not derivable from R 0 . Technique similar to the ordered resolution with selection [Weidenbach, CADE’99]. Bruno Blanchet (INRIA) ProVerif September 2013 66 / 114
Optimizations Elimination of tautologies Elimination of duplicate hypotheses Elimination of hypotheses attacker( x ) when x does not appear elsewhere. Tuples Secrecy assumptions: use conjectures to prune the search space. Bruno Blanchet (INRIA) ProVerif September 2013 67 / 114
Termination The saturation algorithm does not always terminate, but we have proved that it terminates for tagged protocols That is, when each encryption, signature, ... is distinguished from others by a constant tag c i { c i , M 1 , ..., M n } K Large class of protocols Easy to add tags Good design practice [Blanchet, Podelski, Fossacs’03] Bruno Blanchet (INRIA) ProVerif September 2013 68 / 114
Overview 1. A variant of the spi-calculus 2. Intuitive presentation of the Horn clause representation 3. The resolution algorithm 4. Formal translation from the spi-calculus. 5. Extension to correspondences Bruno Blanchet (INRIA) ProVerif September 2013 69 / 114
Translation pi + crypto → Horn clauses We consider a protocol P 0 , executed in the presence of an S -adversary. A protocol is translated into a set of Horn clauses using 2 predicates: attacker( p ) the adversary may have p the message p ′ may be sent on the channel p mess( p , p ′ ) Bruno Blanchet (INRIA) ProVerif September 2013 70 / 114
Translation: attacker clauses For each a ∈ S , attacker( a [ ]) (Init) attacker( b [ ]) where b does not occur in P 0 (Name gen) For each constructor f of arity n , (Constr) attacker( x 1 ) ∧ . . . ∧ attacker( x n ) ⇒ attacker( f ( x 1 , . . . , x n )) For each destructor g , for each rewrite rule g ( M 1 , . . . , M n ) → M , attacker( M 1 ) ∧ . . . ∧ attacker( M n ) ⇒ attacker( M ) (Destr) mess( x , y ) ∧ attacker( x ) ⇒ attacker( y ) (Listen) attacker( x ) ∧ attacker( y ) ⇒ mess( x , y ) (Send) Bruno Blanchet (INRIA) ProVerif September 2013 71 / 114
Translation: protocol clauses ρ : environment (variables, names �→ patterns) h : hypothesis (messages that must be received before reaching the current process) [ [0] ] ρ h = ∅ , [ [ P | Q ] ] ρ h = [ [ P ] ] ρ h ∪ [ [ Q ] ] ρ h , [ [! P ] ] ρ h = [ [ P ] ] ρ h [ [( ν a ) P ] ] ρ h = [ [ P ] ]( ρ [ a �→ a [ p 1 , . . . , p n ]]) h when h = mess( c 1 , p 1 ) ∧ . . . ∧ mess( c n , p n ). Bruno Blanchet (INRIA) ProVerif September 2013 72 / 114
Translation: protocol clauses (continued) ]( ρ [ x �→ x ′ ])( h ∧ mess( ρ ( M ) , x ′ )) [ [ M ( x ) . P ] ] ρ h = [ [ P ] x ′ new variable [ M � N � . P ] ] ρ h ∪ { h ⇒ mess( ρ ( M ) , ρ ( N )) } [ ] ρ h = [ [ P ] [ [ if M = N then P else Q ] ] ρ h = [ [ P ] ]( σρ )( σ h ) ∪ [ [ Q ] ] ρ h where σ is the most general unifier of ρ ( M ) and ρ ( N ). [ [ let x = g ( M 1 , . . . , M n ) in P else Q ] ] ρ h = n ) → p ′ is a rewrite rule of g ](( σρ )[ x �→ σ ′ p ′ ])( σ h ) | g ( p ′ 1 , . . . , p ′ ∪{ [ [ P ] and ( σ, σ ′ ) is a most general pair of substitutions such that σρ ( M 1 ) = σ ′ p ′ 1 , . . . , σρ ( M n ) = σ ′ p ′ n } ∪ [ [ Q ] ] ρ h . Bruno Blanchet (INRIA) ProVerif September 2013 73 / 114
Example: Denning-Sacco protocol Message 1. A → B : {{ k } sk A } pk B k fresh Message 2. B → A : { s } k ( ν sk A )( ν sk B ) let pk A = pk( sk A ) in let pk B = pk( sk B ) in c � pk A � . c � pk B � . ( A ) ! c ( x pk B ) . ( ν k ) c � pencrypt(sign( k , sk A ) , x pk B ) � . c ( x ) . let s = sdecrypt( x , k ) in 0 ! c ( y ) . let y ′ = pdecrypt( y , sk B ) in ( B ) | let k = checksign( y ′ , pk A ) in c � sencrypt(s , k ) � Bruno Blanchet (INRIA) ProVerif September 2013 74 / 114
Example: protocol clauses P 0 = ( ν sk A )( ν sk B ) let pk A = pk( sk A ) in let pk B = pk( sk B ) in c � pk A � . c � pk B � . (! P A | ! P B ) [ [ P 0 ] ] { c �→ c [ ] }∅ Bruno Blanchet (INRIA) ProVerif September 2013 75 / 114
Example: protocol clauses P 0 = ( ν sk A )( ν sk B ) let pk A = pk( sk A ) in let pk B = pk( sk B ) in c � pk A � . c � pk B � . (! P A | ! P B ) [ [ P 0 ] ] { c �→ c [ ] }∅ = [ [ let . . . ] ] { c �→ c [ ] , sk A �→ sk A [ ] , sk B �→ sk B [ ] }∅ Bruno Blanchet (INRIA) ProVerif September 2013 75 / 114
Example: protocol clauses P 0 = ( ν sk A )( ν sk B ) let pk A = pk( sk A ) in let pk B = pk( sk B ) in c � pk A � . c � pk B � . (! P A | ! P B ) [ [ P 0 ] ] { c �→ c [ ] }∅ = [ [ let . . . ] ] { c �→ c [ ] , sk A �→ sk A [ ] , sk B �→ sk B [ ] }∅ = [ [ c � pk A � . . . ] ] ρ 0 ∅ ρ 0 = { c �→ c [ ] , sk A �→ sk A [ ] , sk B �→ sk B [ ] , pk A �→ pk( sk A [ ]) , pk B �→ pk( sk B [ ]) } Bruno Blanchet (INRIA) ProVerif September 2013 75 / 114
Example: protocol clauses P 0 = ( ν sk A )( ν sk B ) let pk A = pk( sk A ) in let pk B = pk( sk B ) in c � pk A � . c � pk B � . (! P A | ! P B ) [ [ P 0 ] ] { c �→ c [ ] }∅ = [ [ let . . . ] ] { c �→ c [ ] , sk A �→ sk A [ ] , sk B �→ sk B [ ] }∅ = [ [ c � pk A � . . . ] ] ρ 0 ∅ ρ 0 = { c �→ c [ ] , sk A �→ sk A [ ] , sk B �→ sk B [ ] , pk A �→ pk( sk A [ ]) , pk B �→ pk( sk B [ ]) } = [ [! P A | ! P B ] ] ρ 0 ∅ ∪ { mess( c [ ] , pk( sk A [ ])) , comes from c � pk A � mess( c [ ] , pk( sk B [ ])) } comes from c � pk B � Bruno Blanchet (INRIA) ProVerif September 2013 75 / 114
Example: protocol clauses P 0 = ( ν sk A )( ν sk B ) let pk A = pk( sk A ) in let pk B = pk( sk B ) in c � pk A � . c � pk B � . (! P A | ! P B ) [ [ P 0 ] ] { c �→ c [ ] }∅ = [ [ let . . . ] ] { c �→ c [ ] , sk A �→ sk A [ ] , sk B �→ sk B [ ] }∅ [ c � pk A � . . . ] ] ρ 0 ∅ = [ ρ 0 = { c �→ c [ ] , sk A �→ sk A [ ] , sk B �→ sk B [ ] , pk A �→ pk( sk A [ ]) , pk B �→ pk( sk B [ ]) } = [ [! P A | ! P B ] ] ρ 0 ∅ ∪ { mess( c [ ] , pk( sk A [ ])) , comes from c � pk A � mess( c [ ] , pk( sk B [ ])) } comes from c � pk B � ] ρ 0 ∅ ∪ [ ] ρ 0 ∅ ∪ { attacker(pk( sk A [ ])) , attacker(pk( sk B [ ])) } = [ [ P A ] [ P B ] attacker( p ) is equivalent to mess( c [ ] , p ) when c ∈ S , by (Listen) and (Send). Bruno Blanchet (INRIA) ProVerif September 2013 75 / 114
Example: protocol clauses (A) P A = c ( x pk B ) . ( ν k ) c � pencrypt(sign( k , sk A ) , x pk B ) � . c ( x ) . let s = sdecrypt( x , k ) in 0 [ [ P A ] ] ρ 0 ∅ ] ρ 0 [ x pk B �→ x pk B ] mess( c [ ] , x pk B ) = [ [( ν k ) . . . ] [ c � pencrypt( . . . ) � . . . ] ] ρ 0 [ x pk B �→ x pk B , k �→ k [ x pk B ] ] mess( c [ ] , x pk B ) = [ = [ [ c ( x ) . . . ] ] ρ 0 [ x pk B �→ x pk B , k �→ k [ x pk B ] ] mess( c [ ] , x pk B ) ∪ { mess( c [ ] , x pk B ) ⇒ mess( c [ ] , pencrypt(sign( k [ x pk B ] , sk A [ ]) , x pk B )) } = { mess( c [ ] , x pk B ) ⇒ mess( c [ ] , pencrypt(sign( k [ x pk B ] , sk A [ ]) , x pk B )) } Bruno Blanchet (INRIA) ProVerif September 2013 76 / 114
Example: protocol clauses (B) P B = c ( y ) . let y ′ = pdecrypt( y , sk B ) in let k = checksign( y ′ , pk A ) in c � sencrypt(s , k ) � [ [ P B ] ] ρ 0 ∅ [ let y ′ . . . ] = [ ] ρ 0 [ y �→ y ] mess( c [ ] , y ) ] ρ 0 [ y �→ pencrypt( y ′ , pk( sk B [ ])) , y ′ �→ y ′ ] = [ [ let k . . . ] mess( c [ ] , pencrypt( y ′ , pk( sk B [ ]))) ] ρ 0 [ y �→ pencrypt(sign( k , sk A [ ]) , pk( sk B [ ])) , y ′ �→ sign( k , sk A [ ]) , = [ [ c � . . . � ] k �→ k ] mess( c [ ] , pencrypt(sign( k , sk A [ ]) , pk( sk B [ ]))) = { mess( c [ ] , pencrypt(sign( k , sk A [ ]) , pk( sk B [ ]))) ⇒ mess( c [ ] , sencrypt(s , k )) } Bruno Blanchet (INRIA) ProVerif September 2013 77 / 114
Proof of secrecy Closed process: P 0 Initial knowledge of the adversary: S finite set of names Clauses for the protocol and the adversary: R P 0 , S . Theorem If attacker(s) cannot be derived from R P 0 , S , then P 0 preserves the secrecy of s from S. Theorem If deriv R P 0 , S (attacker(s)) is false, then P 0 preserves the secrecy of s from S. Bruno Blanchet (INRIA) ProVerif September 2013 78 / 114
Example For the Denning-Sacco protocol, attacker(s) is derivable from the clauses. The derivation corresponds to the description of the known attack. For the corrected version, attacker(s) is not derivable from the clauses: s is secret. Bruno Blanchet (INRIA) ProVerif September 2013 79 / 114
Demo Demo: Denning-Sacco protocol examplesnd/demosimp/pidenning-sacco-orig examplesnd/demosimp/pidenning-sacco-corr-orig Needham-Schroeder public-key protocol examplesnd/demosimp/pineedham-orig examplesnd/demosimp/pineedham-corr-orig Bruno Blanchet (INRIA) ProVerif September 2013 80 / 114
Comparison with typing [Abadi, Blanchet, POPL’02 and JACM’05] We have defined a generic type system for the explained variant of the spi-calculus. Theorem A secrecy property can be proved by the Horn clause verifier ⇔ it can be proved by any instance of the type system. A tight relation between two superficially different frameworks. Bruno Blanchet (INRIA) ProVerif September 2013 81 / 114
Extension to equational theories: Diffie-Hellman Goal: Establish a shared key between two participants g n 0 A → B : Message 1. n 0 fresh g n 1 Message 2. B → A : n 1 fresh A computes k = ( g n 1 ) n 0 , B computes k = ( g n 0 ) n 1 . The exponentiation is such that these quantities are equal. ( g n 1 ) n 0 = ( g n 0 ) n 1 The exponentiation is computed in a cyclic multiplicative subgroup G of Z ∗ p , where p is a prime and g is a generator of G . Bruno Blanchet (INRIA) ProVerif September 2013 82 / 114
Extension to equational theories: Diffie-Hellman example Simplified version of the secure shell protocol (SSH): KExDHInit , g n 0 Message 1. C → S : n 0 fresh KExDHReply , pk S , g n 1 , { h } sk S Message 2. S → C : n 1 fresh where K = ( g n 1 ) n 0 = ( g n 0 ) n 1 and h = H (( pk S , g n 0 , g n 1 , K )). K and h are shared secrets between C (client) and S (server). They are used to compute encryption keys. Bruno Blanchet (INRIA) ProVerif September 2013 83 / 114
Extension to equational theories: other examples XOR: associative, commutative, xor ( x , x ) = 0, xor ( x , 0) = x Primitives whose success is not observable (for decryption for instance) sdecrypt(sencrypt( x , y ) , y ) = x sencrypt(sdecrypt( x , y ) , y ) = x Subtle interactions between primitives Example: XOR and crc crc ( xor ( x , y )) = xor ( crc ( x ) , crc ( y )) Bruno Blanchet (INRIA) ProVerif September 2013 84 / 114
Extension to equational theories We have built algorithms that translate the equations into a set of rewrite rules, which generates enough terms (equal modulo the equational theory). [Blanchet, Abadi, Fournet, JLAP’08] We have shown that, for each trace with equations, there is a corresponding trace with rewrite rules, and conversely. Efficient because it avoids unification modulo. (Standard syntactic resolution can still be used.) Still fairly limited, since it leads to non-termination for many equational theories. (For example, cannot handle theories that contain associativity.) Bruno Blanchet (INRIA) ProVerif September 2013 85 / 114
Recommend
More recommend