Presentation is loading. Please wait.

Presentation is loading. Please wait.

Verification of Security Protocols Secrecy and Authentication in ProVerif April 23, 2012.

Similar presentations


Presentation on theme: "Verification of Security Protocols Secrecy and Authentication in ProVerif April 23, 2012."— Presentation transcript:

1 Verification of Security Protocols Secrecy and Authentication in ProVerif April 23, 2012

2 Try yourself (1) A wants to send a secret message m to B A  B: {|{|msg,m|} skA |} pkB B expects m to be secret. Is it true? Model in ProVerif: -A/B -Initializer -Compromised Find an attack and fix the protocol 1

3 free net, msg, spy. private free initialInitiatorData, initialResponderData. (* The cryptographic constructors. *) fun pencrypt/2. (* public key encryption *) fun sign/2. (* digital signing *) fun enc/1. (* extracts encryption key from a key-pair *) fun dec/1. (* extracts decryption key from a key-pair *) private fun pubkeypair/1. private fun signkeypair/1. (* The cryptographic destructors. *) reduc pdecrypt(pencrypt(x,enc(y)),dec(y)) = x. reduc unsign(sign(x,enc(y)),dec(y)) = x. reduc pubkey(agent) = enc(pubkeypair(agent)). reduc unsignkey(agent) = dec(signkeypair(agent)). (* The queries. *) query attacker: flagA. query attacker: flagB. 2 Encoding (1) A  B: {|{|msg,m|} skA |} pkB

4 (* Initiator process *) let initiator = in(initialInitiatorData,(a,sa)); (* initial data*) !in(net, b); (* get responder's name*) if a<>b then let pb = pubkey(b) in new m; (if b<>spy then new flagA; out(m,flagA)) | let signed = sign((msg,m),sa) in out(net, (a, b, pencrypt(signed,pb))). (* Responder process. *) let responder = in(initialResponderData, (b,db)); in(net, (a,=b,encrypted)); let va = unsignkey(a) in let signed = pdecrypt(encrypted,db) in let (=msg,m) = unsign(signed,va) in if a<>spy then new flagB; out(m,flagB). 3 Encoding (2) A  B: {|{|msg,m|} skA |} pkB Notice again that we are sending flagA on the “secret channel” given by m. And that there is a “if b <> spy” conditional before. This is because we are checking for internal attacker (and since the spy is an internal, she can always get hold of m).

5 (* Initializer process – initial data are sent over a trusted channel *) let initializer = new agent in (* generate agent name *) let pkp = pubkeypair(agent) in (* compute public encryption keypair *) let skp = signkeypair(agent) in (* compute signing keypair *) out(initialInitiatorData, (agent,enc(skp))); (*launch initiator role*) out(initialResponderData, (agent,dec(pkp))); (*launch responder role*) out(net, (agent, enc(pkp), dec(skp))). (* publish the public data *) (* The compromised agent. *) let compromised = let pkp = pubkeypair(spy) in (* compute public encryption keypair *) let skp = signkeypair(spy) in (* compute signing keypair *) out(net, (pkp,skp)). (* publish the keypairs to model compromise *) (* The system. *) process !initiator | !responder | compromised | !initializer 4 Encoding (3) A  B: {|{|msg,m|} skA |} pkB

6 Attack A  M: {|{|msg,m|} skA |} pkM M(A)  B: {|{|msg,m|} skA |} pkB The fix A  B: {|{|pkB,msg,m|} skA |} pkB 5 Attack / Fix

7 Try yourself (2) Consider the following protocol (pkB is the public key of B): A  B: A B  A: N A  B: {s;N} pkB B expects that s is a secret that he shares with A Model this protocol in ProVerif: express B's secrecy expectation as a conditional secrecy assertion Is the conditional secrecy of s guaranteed in the internal threat model? If not, write down the attack trace and fix the protocol 6

8 free net,spy. private free initialInitiatorData, initialResponderData. (* The cryptographic constructors. *) fun pencrypt/2. (* public key encryption *) fun sign/2. (* digital signing *) fun enc/1. (* extracts encryption key from a key-pair *) fun dec/1. (* extracts decryption key from a key-pair *) (* The cryptographic destructors. *) reduc pdecrypt(pencrypt(x,enc(y)),dec(y)) = x. reduc unsign(sign(x,enc(y)),dec(y)) = x. (* A constructor that maps agents to their secret keypairs. *) private fun pubkeypair/1. private fun signkeypair/1. 7 Encoding (1) A  B: A B  A: N A  B: {s;N} pkB

9 reduc pubkey(agent) = enc(pubkeypair(agent)). (* unsignkey/1. *) reduc unsignkey(agent) = dec(signkeypair(agent)). (* The queries. *) query attacker: s. query attacker: flagA. query attacker: flagB. let initializer = new agent; let pkp = pubkeypair(agent) in let skp = signkeypair(agent) in out(initialInitiatorData, (agent,enc(skp))); out(initialResponderData, (agent,dec(pkp))); out(net, (agent, enc(pkp), dec(skp))). 8 Encoding (2) A  B: A B  A: N A  B: {s;N} pkB

10 let initiator = in(initialInitiatorData, (a,sa)); in(net, (b,encb,unsb)); if a<>b then if encb = pubkey(b) then new s; (if b <> spy then new flagA; out(s,flagA)) | out(net,a); in(net,n); out(net,(pencrypt(s,n),encb)). let responder = in(initialResponderData, (b,db)); in(net,a); if a<>b then new n; out(net,n); in(net, (encrypted)); let (s,=n) = pdecrypt(encrypted,db) in if a <> spy then new flagB; out(s,flagB). 9 Encoding (3) A  B: A B  A: N A  B: {s;N} pkB This is put in parallel, but we could also put this in sequence with the rest (I think).

11 let compromised = let pkp = pubkeypair(spy) in let skp = signkeypair(spy) in out(net, (pkp,skp)). process !initiator | !responder | compromised | !initializer 10 Encoding (4) A  B: A B  A: N A  B: {s;N} pkB

12 Attack M(A)  B: A B  M(A): N M(A)  B: {|s;N|} pkB Secrecy s? NO! (spy) Secrecy flagA? NO! Secrecy flagB? NO! Solution A  B: {|{|s;B;N|} skA |} pkB 11 Attack / Fix A  B: A B  A: N A  B: {|{|s;B;N|} skA |} pkB A  B: A B  A: N A  B: {s;N} pkB There are other solutions, but we have to aim at the most simple solution possible (also in the exam, don’t start putting encryption everywhere).

13 let initiator = [...] if a<>b then if encb = pubkey(b) then new s; (if b <> spy then new flagA; out(s,flagA)) | out(net,a); in(net,n); out(net,(pencrypt(sign((s,b,N),sa),encb))). let responder = [...] in(net, (signedencrypted)); let signed = pdecrypt(signedencrypted,db) in let (s,=b,=N) = unsign(signed, unsignkey(a)) in if a <> spy then new flagB; out(s,flagB). 12 Exercise 4: secrecy? Secrecy s? NO! (spy!) Secrecy flagA? YES! Secrecy flagB? YES! A  B: A B  A: N A  B: {|{|s;B;N|} skA |} pkB

14 Try yourself (3) Consider the following protocol, with kA a symmetric key shared by A and server S, and kB a symmetric key shared by B and S: A  B : (A;B;{Na;B} kA ) B  S : (A;B;{Na;B} kA ;{Nb;B} kB ) S  B : ({Na;k} kA ;{Nb;k} kB ) B  A : ({Na;k} kA ) Model this protocol in ProVerif At the end of the protocol, A and B should be able to communicate secretly by using the newly established key k: study the strong secrecy of k and fix the protocol if necessary Note that there are only 3 agents 13

15 fun encrypt/2. reduc decrypt(encrypt(m,k),k) = m. fun host/1. private reduc getkey(host(x)) = x. free c. private free secretA, secretB. private free k. noninterf k. let processA = in(c, hostB0); new Na; out(c, (hostA, hostB0, encrypt((Na, hostB0), kA))); in(c, (m2)); let (=Na, k) = decrypt(m2, kA) in if hostB0 = hostB then out(c, encrypt(secretA, k)). 14 Encoding (1) A  B: (A;B;{Na;B} kA ) B  S: (A;B;{Na;B} kA ;{Nb;B} kB ) S  B: ({Na;k} kA ;{Nb;k} kB ) B  A: ({Na;k} kA )

16 let processB = in(c, (hostA1, =hostB, m2)); new Nb; out(c, (hostA1, hostB, m2, encrypt((Nb, hostB), kB))); in(c, (m3, m4)); let (=Nb, k) = decrypt(m4, kB) in out(c, (m3)); if hostA1 = hostA then out(c, encrypt(secretB, k)). let processS = in(c, (hostA1, hostB1, m2, m3)); let (Na1, =hostB1) = decrypt(m2, getkey(hostA1)) in let (Nb1, =hostB1) = decrypt(m3, getkey(hostB1)) in out(c, (encrypt((Na1, k), getkey(hostA1)), encrypt((Nb1, k), getkey(hostB1)))). 15 Encoding (2) A  B: (A;B;{Na;B} kA ) B  S: (A;B;{Na;B} kA ;{Nb;B} kB ) S  B: ({Na;k} kA ;{Nb;k} kB ) B  A: ({Na;k} kA )

17 process new kA; new kB; let hostA = host(kA) in let hostB = host(kB) in out(c, hostA); out(c, hostB); ((!processA) | (!processB) | (!processS)) 16 Encoding (3) Noninterf? NO! The attacker can impersonate A and get k A  B: (A;B;{Na;A;B} kA ) B  S: (A;B;{Na;A;B} kA ;{Nb;B} kB ) S  B: ({Na;k} kA ;{Nb;k} kB ) B  A: ({Na;k} kA ) A  B: (A;B;{Na;B} kA ) B  S: (A;B;{Na;B} kA ;{Nb;B} kB ) S  B: ({Na;k} kA ;{Nb;k} kB ) B  A: ({Na;k} kA )

18 Noninterf? YES! noninterf secretA, secretB. let processA = [...] out(c, (hostA, hostB0, encrypt((Na, hostA, hostB0), kA))); [...] let processB = [...] out(c, (hostA1, hostB, m2, encrypt((Nb, hostA1, hostB), kB))); [...] let processS = in(c, (hostA1, hostB1, m2, m3)); let (Na1, =hostA1, =hostB1) = decrypt(m2, getkey(hostA1)) in let (Nb1, =hostA1, =hostB1) = decrypt(m3, getkey(hostB1)) in new k; [...] 17 Encoding (4) A  B: (A;B;{Na;A;B} kA ) B  S: (A;B;{Na;A;B} kA ;{Nb;B} kB ) S  B: ({Na;k} kA ;{Nb;k} kB ) B  A: ({Na;k} kA )

19 Queries (properties you want to verify) must be declared in the declaration section Today we study: -Secrecy: queries if the attacker can obtain M − query attacker : M -Many-one correspondence: queries if event M is always preceded by event N − query ev: M ==> ev: N ( ∀ parameters) -One-one correspondence: queries if event M is always preceded by event N, and every trace contains at least as many N-events as M-events − query evinj: M ==> evinj: N 18 Queries

20 query ev: endSend(x,y,z) ==> ev: beginSend(x,y,z). = query ( ∀ x,y,z) (ev:endSend(x,y,z) ==> ev: beginSend(x,y,z)). 19 Authentication and correspondence properties

21 B  A: {|B;n;m 1 |} pkA A  B: {|B;n;m 2 |} skA Does A authenticates to B? = Goal: if one of the parties thinks that the exchange (A;B;m 1 ;m 2 ) happened, then this exchange should have indeed started sometime in the past 20 Example: a simple authentication protocol

22 free c, A, B. private free skA, skB. fun pk/1. fun enc/2. fun sign/2. reduc dec(enc(x,pk(y)),y) = x. reduc check(sign(x,y),pk(y)) = x. query ev:end(w,x,(y,z)) ==> ev:begin(w,x,(y,z)). let initiatorB = new nB; new m1B; out(c,enc((B,nB,m1B),pk(skA))); in(c,x); let (=B,=nB,m2)=check(x,pk(skA)) in event end(A,B,(m1B,m2)). 21 Example: a simple authentication protocol B  A: {|B;n;m 1 |} pkA A  B: {|B;n;m 2 |} skA

23 let responderA = in(c,x); let (=B,nonce,m1)=dec(x,skA) in new m2A; event begin(A,B,(m1,m2A)); out(c,sign((B,nonce,m2A),skA)). process out(c,pk(skA)); out(c,pk(skB)); (!responderA | !initiatorB) 22 Example: a simple authentication protocol B  A: {|B;n;m 1 |} pkA A  B: {|B;n;m 2 |} skA Check this out. Having “=B” in the let means that A knows B;s name beforehand, which is in general an assumption we CANNOT make.

24 Answer: ev: end(w,x,(y,z)) ==> ev: begin(w,x,(y,z)) is false. Attack: B  A: {|B;n;m 1 |} pkA A  M: {|B;n;m 2 |} skA M knows n (B, m 2 ) M  A: {|B;n;m m |} pkA A  B: {|B;n;m 2 |} skA 23 Example: a simple authentication protocol B  A: {|B;n;m 1 |} pkA A  B: {|B;n;m 2 |} skA

25 B  A: {|B;n;m 1 |} pkA A  B: {|B;n;m 1 ;m 2 |} skA Now the same attack is not possible: B  A: {|B;n;m 1 |} pkA A  M: {|B;n;m 1 ;m 2 |} skA M knows n (B, m 2 ) M  A: {|B;n;m m |} pkA A  B: {|B;n;m m ;m 2 |} skA 24 Example: a simple authentication protocol - Fixed

26 We want to include a compromised agent called spy, publishing the spy’s secrets We need to use conditional end-events:... (if a<>spy then event endSend(a,b,m)) |... instead of... event endSend(a,b,m);... Why? The latter is trivially violated for a=spy. 25 Modeling internal threats

27 Other ProVerif features A public key certificate is a pair of an agent name A and her public key pA digitally signed by the key ca of a trusted certificate authority. In ProVerif: sign((A; pA); ca) 26

28 ProVerif allows to insert phase separators into processes:...; phase n;... where n is a positive integer The phase separator indicates that the process now enters phase n When a process starts running, it is in phase 0 When a process enters the next phase, all processes that have not yet reached the end of the previous phase are discarded In that sense, one can understand the phase separators as global synchronization commands 27 Other ProVerif features

29 You can query for standard secrecy up to the end of a certain phase: query attacker: x phase n. This queries if x remains secret up to the end of phase n. The query is violated if an attacker can get x before the process has started executing phase n Other ProVerif features

30 Non-interference allows us to reason about the secrecy of guessable messages that are meant to be kept secret. -Example: Electronic votes. These are easily guessable, because in a typical election there is only a small number of candidates. Standard secrecy is often appropriate for reasoning about messages that are virtually impossible to guess. -Example: Cryptographic session keys. Somewhat in between are weak secrets. These are impossible to guess online, but offline attacks are possible. -Example: Passwords. -An offline attack works by first collecting some data online and then running a computationally intensive analysis offline. -Example: Searching a dictionary for likely passwords. -Query in ProVerif: weaksecret w. 29

31 Other ProVerif features ProVerif can soundly verify testing equivalence (observational equivalence). ProVerif verification of testing equivalence is incomplete. -This incompleteness does show in practice (much more often than the incompleteness for standard secrecy and correspondence assertions). To query for testing equivalence of two processes, you need to express the two processes “as one”. ProVerif choice-construct tells ProVerif the spots where the two processes differ: M,N ∈ Msg ::=... | choice[M,N] |... -fst(P): process obtained from P by replacing every occurrence of choice[M,N] by M -snd(P): process obtained from P by replacing every occurrence of choice[M,N] by N -ProVerif tries to prove fst(P) ≃ snd(P). 30

32 In principle, you can query for observational equivalence of arbitrary processes P and Q using the choice construct: R = if choice[m,n] = m then P else Q Then fst(R) ≃ snd(R) iff P ≃ Q However, ProVerif is usually unable to verify fst(R) ≃ snd(R) due to its incompleteness 31 Other ProVerif features

33 fun hash/1. free net. process new n; out(net, choice[n, hash(n)]). This asks ProVerif to prove: new n; out(net, n) ≃ new n; out(net, hash(n)). ProVerif succeeds on this. Intuitively, this equivalence holds, because to an observer both n and hash(n) look completely arbitrary. 32 Other ProVerif features

34 free net,n,m. process out(net, choice[n,m]); out(net, choice[m,n]) This asks ProVerif to prove: out(net,n); out(net,m) ≃ out(net,m); out(net,n) These are not equivalent 33 Other ProVerif features

35 34 Do it yourself Consider the following protocol: B  A : nb;text1 A: begin(A,B,nb) A  B : pkA;A;{na;nb;text2} skA B: end(A,B,nb) B: begin(B,A,na) B  A : pkB;B;{na;text3} skB A: end(B,A,na) -A public-key infrastructure is assumed: pkA, pkB are the public keys of A and B, respectively -skA, skB are the signing keys of A and B, respectively -text1,text2,text3 are publicly known messages Write a model of this protocol in ProVerif Check whether the protocol correctly realizes mutual authentication between A and B; fix it if needed


Download ppt "Verification of Security Protocols Secrecy and Authentication in ProVerif April 23, 2012."

Similar presentations


Ads by Google