NEXt generation Techno-social Legal Encryption Access and Privacy nextleap.eu

Grant No. 688722. Project started 2016-01-01. Duration 36 months.

DELIVERABLE D4.3

PRIVACY PRESERVING MESSAGING FORMAL MODELLING

Karthikeyan Bhargavan, Bruno Blanchet, Iness Ben Guirat, Harry Halpin, Benjamin Lipp, Nadim Kobeissi (INRIA)

Beneficiaries: INRIA (lead) Workpackage:4 Description: Models of messaging protocols from WP2 with respect to a number of possible primitives for properties related to decentralization,privacy, security, and anonymity.

Version: 1.0 Nature: Report (R) Dissemination level: Public (PU) Pages: 107 Date: 2018-12-31

Project co-funded by the European Commission within the Horizon 2020 Programme. D4.2 NEXTLEAP Grant No. 688722

Contents

Executive Summary 3

1 Introduction 4

2 W3C Web Authentication (Authentication) 5

3 Signal Protocol (Synchronous Messaging) 22

4 Noise (Network-level Encryption) 58

5 Wireguard (VPN) 83

2 D4.2 NEXTLEAP Grant No. 688722

Executive Summary

In this deliverable, we present the results of formally verifying various protocols relevant to privacy-preserving messaging. In general, we verify their security properties, although consideration is taken if possible on privacy and anonymity although these two latter properties are hard to verify with the current toolset. We focus on ProVerif, veriying under the Dolev-Yao symbolic model in order to discover if a protocol is secure, and we also present some new work using CryptoVerif, which creates computational proofs. We detail the verificaton of the W3C Web Authentication API, the Signal Protocol, the Noise Protocol Framework, and the Wireguard VPN.

3 D4.2 NEXTLEAP Grant No. 688722

1 Introduction

NEXTLEAP has four main technical components: federated identity, e-mail (originally entitled “asynchronous messaging” although used by Delta.chat for instant messaging), secure messaging (originally entitled “syn- chronous messaging” although secure messaging protocols like Signal and MLS now handle messages in the synchronous setting, just not backwards compatible with e-mail), and privacy-enhancing analytics. The formal verification of federated identity project ClaimChain was already given in D4.1 via its specification in F. The initial ProVerif model of PGP was given D2.3, detecting the authentication attacks that are inherited in Autocrypt. The Message Layer Security Protocol) was described as well in D2.3, and work on its formal specification is still ongoing in F as the standard matures. Due to the statistical nature of the “wisdom of the crowds” analytics, it cannot be formally verified with current tools.

Therefore, this deliverable focuses on the completed formal verification work on security (and if possible, privacy, and anonymity) properties done during NEXTLEAP on the fundamental building blocks of secure messaging: Secure authentication, the Signal Protocol, network-level encryption, and VPN primitives (which in our case are a subset of network level encryption. These components, which are vital parts of messaging and will be likely deployed in conjunction with the IETF MLS standard and Autocrypt. These components and their relationship to various protocols are detailed below:

W3C Web Authentication (Authentication): One component that is vital for all authentication systems is • to identify the user. However, this act of authentication is typically done via , and is out of scope of the Autocrypt and MLS work. Of course, the possession of a key is assumed to be part of the federated identity system of Claimchain, as well as in Autocrypt and MLS. However, how key material is used to authenticate to an actual messaging system is left undefined. A new standard, W3C Web Authentication, defines a new protocol for using key material, such as those stored in smart cards, to authenticate. This protocol was modelled for security and privacy with considerations on using DAA (Direct Anonymous Authentication) in the Masters thesis of Iness Ben Guirat at Inria, under the supervision of Harry Halpin. We found the handshake to be secure, but there to be possible violations of privacy due to the re-use of device-specific key material by the user.

Signal Protocol (Synchronous Messaging): The entire NEXTLEAP project is inspired by the rise of • end-to-end encryption, but the actual popular Signal protocol for messaging was not formally specified. This protocol, which inspired the work on MLS and the modernization of encrypted email of Autocrypt, was formally verified in Proverif by Nadim Kobeissi as part of his Ph.D. dissertation at Inria under the supervision of Bruno Blanchet and Karthik Bhargavan. This work revealed an unknown key share attack.

Noise (Network-level Encryption): Most and e-mail based protocols like PGP-based Autocrypt • use TLS, but for point to point communication, there are much simpler and less complex Diffie-Hellman handshake-based protocols that can be used. The Noise protocol specifies a framework for specifying these protocols, and WhatsApp uses one of the Noise Protocol frameworks. Never before verified, the security of most of the Noise Protocol framework was formally verified in Proverif by Nadim Kobeissi at Inria under the supervision of Karthik Bhargavan.

Wireguard (VPN): One of the Noise protocol handshakes for network-level encryption forms the basis • of Wireguard, a new VPN protocol. This VPN protocol is compatible with any network traffic, including Autocrypt, MLS, and more. This was formally verified in the Masters thesis of Benjamin Lipp at Inria under the supervision of Bruno Blanchet, Karthik Bhargavan, and Harry Halpin.

4 D4.2 NEXTLEAP Grant No. 688722

2 W3C Web Authentication (Authentication)

5 Deliverable D4.2 NEXTLEAP Grant No. 688722

1 Introduction

For security to be a science, methodologies that can scientifically guarantee security and privacy properties such as formal verification need to be applied consistently to security issues. One of the largest problems damaging the security of modern information systems is the inability of users to generate and consistently use unique high-entropy passwords per domain. Fundamentally the entire idea of a as symmetric secret for authentication is in need of replacement by asymmetric . In this paper, a proposed standard for public-key authentication, W3C Web Authentication, is analyzed using the formal verification. After describing the state of the art of formal verification in Section 2, we describe the background of the issue of authentication and the development of the W3C Web Authentication protocol in Section 3. In Section 4, each step of the W3C Web Authentication protocol is informally described. Using the formal verification tool ProVerif described in Section 5, we automatically formally verify the security properties of W3C Web Authentication in Section 6 and prove that the claimed privacy properties of W3C Web Authentication can be violated. A range of fixes outlined but not mandatory in the specification, such as the use of Direct Anonymous Authentication, are described in Section 7 and next steps for the scientific application of formal verification in terms of future protocols in Section 8.

2 The Science of Security and Formal Verification

Security has far too long been viewed as a black art based more on intuition than science, with protocols and cryptographic primitives often judged due to the reputation of their creator.1 In contrast, by definition a science of security would place the security properties of techno-social systems on a scientific basis, including cryptographic primitives, the composition of those primitives into cryptographic protocols, and the embedding of these protocols into user behavior and the wider social world. This is a demanding task, and formal approaches have allowed tremendous amount of progress in the formal definition and verification of security properties [1]. Formalized game-hopping proofs have put the field of cryptography on a sound basis and can work over protocols of considerable complexity, but there exists still much work to be done to put this methodology into production for protocols. Although manual proofs for protocols do exist, even if specified in formal detail, complex protocols have large state spaces where a move in the protocol that was not foreseen by the designers may lead to the security properties of the entire protocol being violated. The classic example is that of the Needham-Shroeder protocol [2], whose security flaws were only discovered more than twenty years afterwards using formal methods [3].

A science demands a methodology and the methodology of formal verification tools provides a promising path for the verification of the security properties, and even privacy properties, of cryptographic primitives and protocols. Formal verification is the creation and checking of the properties of a cryptographic protocol or primitive not via proofs constructed by hand, but by proofs constructed in a fully mechanized manner. This is necessary as often the manual construction of proofs may, by sheer human accident, miss either seemingly routine aspects of the protocols that may violate their security and privacy properties, or that the level of complexity of the protocol is so such that the number of states that need to be inspected by hand are far greater than are possible within a reasonable amount of time. In modern protocols like TLS 1.2, it is precisely these kinds of obscure errors, such as the “triple handshake” renegotiation attack caused by complexity that were discovered via formal analysis [4].

While testing can help assess the security properties of a program, there will likely behavior of any program that is untested and can lead to the security properties being violated. Formal verification is the only approach that can guarantee correctness and security of a program. As formal verification via manual proofs are unlikely to cover all aspects of the security properties in every case, formal verification can be automated to explore the very large state spaces generated by programs. Note that this mechanized exploration is always within the constraints of the formalism used, so the entire state space may not be explored. Nonetheless, modern work in proof assistants

1For example, one may look at the CryptoForum Research Group debates between Daniel Bernstein and Microsoft Research that led to the fracturing of Microsoft and Google eco-systems in terms of elliptic curve support in TLS. See https://datatracker.ietf.org/ doc/rfc7748/

6 Deliverable D4.2 NEXTLEAP Grant No. 688722 such as Coq and the SMT solvers like Z3 deployed by F* [5] has progressed to the point where they can explore efficiently very large state-spaces that would otherwise be impossible via manual proofs.

Progress has accelerated recently. Tools such as ProVerif can model protocols for security properties such as the leakage of secret under the symbolic model [6], while new tools such as CryptoVerif allow even the automation of proofs under the computational model used in game-hopping proofs [7]. Two large advances have been the ability to test for secret independence by tools like ct-verif, i.e. constant-time verification, where it can be proven that the information flow and therefore implementation time is constant regardless of any secret material [8]. Another large advance has been the verified compilation of formally verified code in a higher-level language such as F* into a safe subset of C, thus allowing formally verified code to actually be run in real-life environments [9], which is useful is one wants to create a new implementation of a protocol. If one wants to formally model an abstract standard like W3C Web Authentication that already has multiple implementations, ProVerif would be the tool of choice, as the browser vendors have already implemented the protocol.

However, the main problem is that these tools are typically deployed to verify implementations of standards of cryptographic primitives (NIST) or protocols (IETF, W3C, IEEE, ISO) after the standard is complete. In general, the methodology of formal verification would be more productively applied during the development of a new protocol itself, so that the standard’s specification is assured to fulfill its security and privacy requirements. There has been work on API analysis like the W3C Web Cryptography API [10], but this analysis was done after the standard itself was completed, although efforts in TLS 1.3 have incorporated formal verification into the standardization process [11].

3 Background

One new standard that is still being completed but has not yet been subjected to formal verification is W3C Web Authentication. The W3C Web Authentication protocol was created in order to get rid of passwords on the Web. Previous studies [12] and a large number of password database breaches have demonstrated that passwords (which are equivalent to a symmetric secret shared between the server and client) tend to be low-entropy and difficult, if not impossible to secure due to the increasing amount of power being deployed by brute-force attacks.2 This has long been recognized as an outstanding problem and there has been a large array of previous research, ranging from password authenticated key exchange (PAKE) and smartcard-based solutions, but they have all failed to reach large market penetration due to patents and the inherent issues in deploying new technology to millions of users.3 Therefore, researchers have long pointed out that a standard API for authentication across all web browsers would be one possible solution [13].

As the result of the W3C Workshop on Web Cryptography Next Steps: W3C Workshop on Authentication, Hardware Tokens, and Beyond in 2014, large vendors such as Paypal and all major browser vendors (Google, Microsoft, )4 have started work on a new standard for authentication at the World Wide Web Consortium (W3C).5 The W3C is the world’s leading body, responsible for standards like HTML and crypto- graphic standards such as the W3C Web Cryptography API that allow the access of cryptographic primitives in the Javascript runtime environment.

The core concept of W3C Web Authentication is to use asymmetric key material on user’s devices to authenticate a user to a web server rather than passwords [14]. W3C Web Authentication (sometimes called “WebAuth” or “WebAuthn”) is implemented by building a Javascript protocol that can take advantage of key material on any device, called the , in a generic manner. can range from key material on hardware keys such as Yubikeys or key material in the secure enclave of . Not only does this allow for the authentication secret (the private key) to remain protected on the client device, it also means that this secret is unknown to the user and therefore cannot be stolen through . A user with a device

2Onlinehashcrack.com 3See US Patent CN105721153 A. 4Except Apple currently, although Apple often does not participate in the creation of new W3C standards. 5https://www.w3.org/2012/webcrypto/webcrypto-next-workshop/ 7 Deliverable D4.2 NEXTLEAP Grant No. 688722 that supports W3C Web Authentication can register directly with key material using one factor cryptographic authentication. Cryptographic material can be used as a factor in multi-factor authentication (in addition to traditional password-based authentication or other factors like SMS and phone calls).

The concept behind W3C Web Authentication was first articulated in PhoneAuth [15], a framework that ensures user authentication by opportunistically providing cryptographic identity assertions from a user’s mobile phone while the user authenticated using passwords with another device, such as their laptop. Previous standards around two-factor authentication called (U2F) [16] and Universal Authentication Framework (UAF) for one-factor cryptographic authentication were developed by FIDO (Fast IDentity Online) [15], a non-profit formed in 2012 with 250 corporate members. The FIDO UAF specifications not only saved users from using passwords, but specified recovery procedures when they forget a password as well as the integration of personal identification information such as biometric data stored locally on the user’s device, as the local storage of biometrics and other personal information is intended to facilitate the concerns of users regarding personal data stored on an external server on the cloud. U2F was shipped with USB tokens deployed by companies internally such as Google and Github, and UAF with smartphones such as the Samsung Android.

The UAF and U2F specifications were simplified and unified in the FIDO 2.0 specification [17] that removed all references to specific factors such as biometrics and instead developed a unified API for the development that could deploy any number of authentication factors. The older FIDO protocol was formally verified using ProVerif, and it was detected that a missing check for an AppID could lead to attacks [18]. The AppID was removed in W3C Web Authentication and replaced by an RP ID whose checking is enforced. The FIDO 2.0 specification was submitted as W3C Member Submission to the W3C in 2015, and the W3C subsequently formed a W3C Working Group in 2016 to standardize the W3C Web Authentication API across all browsers. Google already accepts consumer-facing FIDO 1.0 and W3C Web Authentication using Yubikeys and other supported USB hardware tokens, as shown in Figure 1. A number of large changes from the FIDO 2.0 specification have happened, such as the simplification of the registration and authentication protocol, the enforcement of the same origin policy for privacy [19], and the use of asynchronous Javascript. Another related specification being developed at the IETF (Internet Engineering Task Force) in parallel to W3C Web Authentication API [20] is HTTPS Token Binding. The IETF HTTPS Token Binding standard is separate from W3C Web Authentication, although it is used to provide a TLS identifier for W3C Web Authentication if the client supports it.

Figure 1: Google Two-Factor Authentication Support

8 Deliverable D4.2 NEXTLEAP Grant No. 688722

4 The W3C Web Authentication Protocol

The W3C Web Authentication protocol ensures strong user authentication using asymmetric cryptography [14]. W3C Web Authentication defines the security goals of their authentication protocol in terms of the protocol being resistant to phishing attacks, man-in-the-middle attacks, and unlinkability between user accounts and services.

A user is trying to authenticate to a relying party (RP) such as a . The user is assumed to have one or more authenticator(s). For authenticating a user the authenticator has a set of credential keys, where new keys are created per origin, possibly derived via functions like key derivation (although this is unspecified) from a master key. Also, each authenticator has attestation keys, an asymmetric keypair for the identification of the authenticator or type of authenticator. A public key credential is created and stored by an authenticator for each relying party, where separate relying parties are defined by origins. An origin is defined as the domain name (including top-level domain), protocol, and port of a website such that https://mail.google.com has the origin google.com and thus shares a domain with https://maps.google.com but not with https://maps.apple.com or http: //evil.com [19].

Figure 2: An example challenge-response flow

As given in Figure 2, authentication is done via cryptographically signing a challenge response protocol from the server. In detail, the private credential key never leaves the device but signs a challenge given by the server (1). A user interaction (such as a button press on a ) is required for the user to sign the credential, which gives a “proof of presence” of a human being (2), as opposed to an automated attacker that is trying to brute force the signature from a captured device. Then the signed challenge is sent back to the server (3), registering the public key of the user or authenticating the user (4). The server challenge is a nonce, as well as its origin in order to prevent phishing and a HTTPS Token Binding (a number generated by the server that identifies a particular TLS channel) is given to prevent man-in-the-middle attacks. Unlinkability is preserved by having different credential keys for different origins. The public key credential can only be accessed by origins belonging to that Relying Party. These properties and their threat models are verified in Section 6. The protocol has two distinct phases: 1) At least one registration phase to enroll a user’s authenticator 2) One or more authentication phases, with a new one commencing when the user visits the website. During registration, a public key credential is created on a client’s authenticator and associated by a relying party with the user’s account on that relying party. In contrast, in the authentication phase, the challenge is sent from the relying party to the client and the relying party is presented by the client with an assertion proving the presence of the user who registered the public key credential and so authenticates the user. For signatures, the W3C Web Authentication protocol uses ECDSA (Elliptic Curve Digital Signature Algorithm). Currently, W3C Web Authentication supports the NIST P-256 curve.

4.1 Registration

In the registration phase, the user and a Relying Party work in concert to create a public key credential and associate it with the RP’s account for that user.

1. The RP (server) sends a challenge (a nonce) and an RP identifier to the user’s client. The browser checks to see the RP identifier matches the origin of the sender.

2. The authenticator generates a new keypair for the origin of the RP, associating that credential keypair with that RP’s identifier.

9 Deliverable D4.2 NEXTLEAP Grant No. 688722

3. The authenticator returns to the RP, via the browser, a signed attestation certificate that includes an attestation key for the authenticator in addition to the challenge and the user’s public key associated with the RP, along with other associated data (i.e. the origin).

4. The RP verifies the nonce and associated data before extracting the information in the attestation certificate. The RP associates the credential public key with the account (handle) of the user.

In the authentication phase, the authenticator attempts to cryptographically prove to a Relying Party that the user controls the credential private key associated with a previously-registered public key credential. A counter is added to make sure an authenticator is not “cloned” (when there are two different authenticators operating in parallel claiming to be the same authenticator).

1. The RP sends a challenge (a nonce) and the RP identifier to the user along with a handle previously registered for a keypair by the RP. As in registration, the browser checks to see the RP identifier matches the origin.

2. The browser prompts the user to select a credential, possibly from a list of credentials associated to the RP. The user consents for using this credential and generates an assertion signature with his private key for that credential.

3. The authenticator signs the challenge and associated data.

4. The authenticator, via the browser, returns a signed challenge and a counter to the RP.

5. The RP verifies the challenge, the counter, and verifies the signature of the user using the credential public key previously associated during registration with their account.

5 ProVerif

ProVerif [6] (“Protocol Verifier”) is an automatic tool for formal verification under the symbolic Dolev-Yao [21]. In a Dolev-Yao model, the cryptographic primitives are assumed to be working and are called as functions that an attacker cannot change, although the attacker may use the results of these cryptographic functions. In the threat model of Dolev-Yao, the attacker can observe the channel between participants in a protocol and can read, alter, block, and inject messages.

ProVerif takes as a representation of a protocol described by Horn clauses and automatically tries to prove the security properties of the protocol by simulating an attacker over multiple sessions of the protocol. ProVerif can create generic predicates of any arity, but ProVerif includes special built-in predicates for cryptography defined with equational theories, including symmetric public-key cryptography (encryption and signatures), hash functions, and Diffie-Hellman key agreement. It can handle an unbounded number of sessions of the protocol and an unbounded message space. ProVerif can prove the following properties:

secrecy: The attacker cannot obtain a secret. • authentication: Modelled as a a correspondence property, namely that one event implies another event. • In the case of authentication, a server accepts authentication if and only if the user accepts the same authentication. Informally, the user cannot authenticate to another server, or an attacker cannot impersonate a user.

strong secrecy: The attacker can not identify the difference between any session of the protocol if the • value of the secret changes.

equivalences: Processes that can be proven to differ only by terms. • Due to its formalism, ProVerif can generate false attacks but if ProVerif claims that the protocol satisfies some property, then the property is actually satisfied. When the ProVerif cannot prove a property, it tries to reconstruct an attack by automatically generating an execution trace of the protocol that falsifies the desired property. 10 Deliverable D4.2 NEXTLEAP Grant No. 688722

M,N ::= terms x v a r i a b l e a [ M1 ,..., Mn ] name f ( M1 ,..., Mn ) constructor F : : = pred ( p1 ,..., pn ) f a c t R : : = F ... F F Horn clause 1 ∧ ∧ n ⇒

Figure 3: Syntax of Horn Clauses Representation

P,Q,R ::= processes 0 null process P Q parallel composition | !P replication i f M = N then P else Q conditional vn.P name restriction

Figure 4: Syntax of the applied π calculus

5.1 Horn clauses

A protocol in ProVerif is represented by a set of Horn clauses; the syntax of these clauses is shown in Figure 3 and they have a standard Horn Clause formal semantics [6]. In Figure 3, x ranges over variables, a over constants (called “names”), f over functions, and p over predicates. The term M represent messages that are exchanged between participants of the protocol. A variable can represent any name. Names represent atomic values, such as keys and nonces. Each participant has the ability to create new names: fresh names are created at each run of the protocol. Names are considered as functions of the messages previously received by the principal that created the name. Thus, names are distinguished only when preceding messages are different in a protocol session. The security properties are given as queries over the Horn clauses, i.e. Horn clauses that may be true or false.

5.2 The applied π calculus

As ProVerif describes multiple phases of a protocol with possible branches, it describes these phases (i.e. the execution of a protocol described via Horn clauses over multiple sessions) as processes using the applied π calculus [22] introduced by Abadi and Fournet [23]. The applied π calculus is an extension of the π calculus with function symbols defined by an equational theory. Abadi and Fournet added cryptographic functions using equational theories [23], whose equational theories are used to define cryptographic functions in ProVerif. Note that when ProVerif is run, these statements in the π calculus are transformed into Horn clauses.

In particular, we will use the senc (symmetric encryption) and sdec (symmetric decryption) cryptographic functions to model TLS and sign and checksign to sign and check public key signatures. We will also use the built-in type nonce for nonces. Under a Dolev-Yao model, a bitstring type is used for generic messages, such as a credential. The protocol as a process initially runs in the first phase; then at some point protocol in this phase can stop and processes of the next phase are run and so on. State may be passed between phases, such as the transfer of compromised keys.

To put it all together, a ProVerif protocol description Σ has two major parts: A sequence of Horn clauses ∆ ....∆ that contain names (variable and constant), constructors and • 1 n destructors, equations (needed by cryptographic functions), processes and queries. Queries define the security and privacy properties to prove. 11 Deliverable D4.2 NEXTLEAP Grant No. 688722

P, the top-level process which then uses ∆ ....∆ as its toolkit for creating a flow for the protocol. • 1 n The replication !P, representing an unbounded number of copies of P in parallel, launches the protocol flow. During verification, tables store persistent state such that the process insert a(M1,...,Mn);P inserts the entry (M1,...,Mn) in Table a, and runs P. The process get a(=M1,x2,...,xn) in P retrieves an entry (N1,...,Nn) in Table a when N1 = M1. If such an entry is found, then x2,...,xn is bound to N2,...,Nn and runs P. Tables can be used to store values such as nonces and secrets that maintain state between multiple runs of the protocol.

When ProVerif is used to formally verify the security properties of a protocol, it runs a resolution algorithm on the representation of the protocol, given as Horn clauses (∆1....∆n). A query of a security property is then ∆q, i.e. a statement of a successful attack. Usually, this is attacker(K), where the statement is that the attacker knows secret material K. The resolution algorithm tries to derive ∆q from ∆1....∆n. If it does, then the execution trace of the derivation is the attack. If it does not find an attack, the query is false. Note that ProVerif is sound such that if an attack exists in the protocol, it is found by the resolution algorithm. However, ProVerif is incomplete such that false attacks can be found (i.e. each attack should be manually checked) and insofar as for certain protocols ProVerif may not terminate.

6 Formal Verification of W3C Web Authentication

In this section, we describe the process of formally verifying the W3C Web Authentication using ProVerif. For each section, we describe the threat model and then demonstrate the protocol’s formalization using ProVerif, and finally if the properties were proven to hold by process of formal verification. In detail, we describe how we model the user and the server for both authentication and registration phases, and how we formalize privacy in terms of the same origin restriction in Section 6.3. The description of the protocol in ProVerif is given in boxes.

6.1 Components

In more detail, the following key material-related components are used in W3C Web Authentication. Given the complexity of W3C Web Authentication, we do not verify many components that are not used in key material-based operations. Note that as ProVerif does not have a representation of numbers so we cannot verify the counter, so it is left out of the model. We assume that the channel between the token and the browser is secured and so model both as a singler user entity. We assume the network connection is secured successfully using TLS, which we explicitly model via symmetric key encryption. The following variables in our model are used in both phases:

Credential public key (pk ): “The public key portion of a Relying Party-specific credential key pair, • A generated by an authenticator and returned to a Relying Party at registration time” [14]. For each relying party, the user A generates a new credential public key for future use.

Credential private key (sk ): “The private key portion of the credential key pair is known as the credential • A private key” [14]. The authenticator sign each message to a RP with this key, and it’s usually saved in the authenticator or in the user A’s platform.

Credential ID (credential ): “A probabilistically-unique byte sequence identifying a public key credential • ID source and its authentication assertions” [14]. This uniquely identifies a credential.

Relying Party Identifier (RP ): “A valid domain string that identifies the Relying Party” [14], with the • id domain by default being the origin of the RP (server S).

Nonce (N ): A nonce is an arbitrary number that may only be used once to prevent replay attacks, and • S used as part of the challenge in the WebAuth protocol sent by the server S.

Attestation certificate (sign(att)): “An attestation statement contains a signature by an attestation private • key over the attested credential public key and a challenge, as well as a certificate or similar data providing provenance information for the attestation public key, enabling the Relying Party to make a decision to trust 12 Deliverable D4.2 NEXTLEAP Grant No. 688722

the attestation or not”’ [14]. We simplify the model of the specification by considering the attestation object in the registration as a single signed object including the attested credential data and the challenge.

Attestation public key (att pk ): “The attestation public key conveyed in the attestation certificate to verify • A the attestation signature” [14], of user A for attestation att.

Attestation private key (attsk ): The private key needed to “sign the Relying Party-specific credential • A public key (and additional data) that it generate” [14] of user A for attestation att.

6.2 Security Properties of W3C Web Authentication

In this section, the ProVerif model is described. Code samples in ProVerif syntax are given in boxes, illustrating the parts of the model as needed.6

6.2.1 Threat Model

The threat model of security properties is a network attacker, an attacker that can control all messages on a channel [24]. In passive attacks, the attacker can intercept and read all messages sent on the network and can run arbitrary computations on messages. In active attacks, the attacker can compute messages and also alter, block, and send its own messages on the network, including messages involving computation.

6.2.2 Security Goals

We want to prove integrity, which we can prove by showing that no secret key material can be known by the attacker, as is done via “phishing attacks,” and so all messages maintain integrity. We also want to prove authentication, i.e. the user can only authenticate to the server they have registered to (preventing “man in the middle” attackers) so the attacker can not impersonate the user.

6.2.3 ProVerif Description

In our model, we assume that a valid TLS connection is established before commencing the W3C Web Authenti- cation protocol. As the network traffic is encrypted by TLS, we model that each message sent on the channel is encrypted via a symmetric shared secret. We do not model HTTPS Token Binding and other associated non-cryptographic data outside the RP ID. To simplify the explanation, we use the term “server” rather than “relying party” (RP) in our model and do not model provenance data (outside of the RP ID) like Token Binding.

During the registration phase the server (RP) S sends a challenge and RPid to the user A. The user generates the attestation certificate, signs it with their attestation secret key, and sends back to the server. S A : (N ,RP ) → s id A S : sign(N ,RP , pk → s id A credentialID,att pkA),attskA)

When the server receives the attestation certificate, the server verifies the certificate of the authenticator (via the signature) and the challenge as well as RP ID.

In the authentication phase, the server sends another challenge to the user. The user receives another challenge, signs it and returns a response signed with the credential public key to the server (checking origin, although we do not model any other additional data such as HTTPS Token Binding and user handles associated with Credential IDs).

6The full ProVerif code is available from https://github.com/hhalpin/webauthn-model. 13 Deliverable D4.2 NEXTLEAP Grant No. 688722

S A : (N ,RP ) → s id A S : sign((N ,RP ),sk ) → s id A The server verifies the signature with the user’s public key for his credential. Once the signature is verified, the user is authenticated.

In our ProVerif model, subscripts are concatenated to names in variables (i.e. N Ns). The symmetric key s → established by TLS is given by k.

To model W3C Web Authentication in ProVerif, we query whether the attacker can get knowledge of any key material or spoof the Credential ID via the following queries: query attacker(attskA), query attacker(attpkA), query attacker(k), and query attacker(credentialID). To verify the authentication property, we created an authentication procedure with two events, sentChallengeResponse and validChallengeResponse. The first event triggers the second event if the authentication is successful in order to prove authentication.

event sentChallengeResponse(bitstring,bitstring). event validChallengeResponse(bitstring,bitstring). query m1:bitstring,m2:bitstring; event(validChallengeResponse(N,s)) = ⇒ event(sentChallengeResponse(m1,m2)).

A user is modelled as a set of credential keys and attestation keys on their authenticator. Credential keys are given a credential ID.

let processUser ( k: key,credentialID:bitstring, attskA: AttestationPrivatekey, attpkA:AttestationPublicKey) =

A user has two functions, one for registration and another for authentication. If a user receives a challenge nonce, it responds with the signed attestation credential if they have not registered with the server before. Therefore, the user generates a new credential keypair (pkA,skA) and returns an attestation credential signed with their attestation secret key attskA.

in(c,s:bitstring); let(Nu:nonce,RP:host) = sdec(s,k) in new skA:skey; let pkA = spk(skA) in out(c,senc(signAtt((spk(skA), attpkA,credentialID,Nu),attskA),k));

If a user receives a challenge nonce and it has received the message before, then it returns the attestation credential signed with its already created credential key skA.

14 Deliverable D4.2 NEXTLEAP Grant No. 688722

in(c,s:bitstring); let mess1 = sdec(s,k) in event sentChallengeResponse(mess1, sign(senc(mess1,k),skA)); out(c,sign(senc(mess1,k),skA)).

The second party in the Web Authentication protocol is the server, which is identified with its “origin” RPid and has a shared symmetric TLS key k with the user.

let processServer (k: key, RP id:host) =

During registration, the server sends a nonce Ns1 with its RPid. When it receives a message, it stores the received credential key pkY1 to associate it with user A and checks to make sure the attestation certificate is signed by the attestation key att pku1.

new Ns1 : nonce; out(c,senc((Ns1,RP id),k)); in(c,s:bitstring); let m = sdec(s,k) in let (pkY1: pkey,attpkU1:AttestationPublicKey, credUser: bitstring,Nu:nonce) = getmessAtt(m) in let ver = checksignAtt(m,attpkU1) in

During authentication, the server checks that the received nonce Nu matches Ns1. Then the server checks to make sure the signed challenge returned by the user is signed by the key pkY1. Only then is the authentication event validChallengeResponse triggered.

if (Nu = Ns1) then (new Ns2 : nonce; let mess = nonce to bitstring ( Ns2 ) in out(c,senc ((mess,RP id),k)); in(c,s:bitstring); let m1 = sdec(s,k) in let m2 = checksign(m1,pkY1) in let m3 = getmess(s) in if (m3 = getmess(s)) then event validChallengeResponse(m3,s))

In order to determine if an attacker can impersonate a user via a “phishing” or “man in the middle attack,” we can query to determine if an attacker can reach the authentication event, as could be done if the attacker could gain knowledge of the key material of the user and so register themselves as the user (phishing), or intercept the challenge and send their own signature which would be accepted by the server as the user’s signature (“man in the middle”). The results of running ProVerif over the following model resulted in no knowledge of the key material

15 Deliverable D4.2 NEXTLEAP Grant No. 688722 or credential ID being found by the attacker, and a validChallengeResponse from the server always was preceded by a sentChallengeResponse from the user. Therefore, no phishing and “man in the middle” attacks were found, so we can surmise that the W3C Web Authentication securely authenticates users to servers.

6.3 Privacy Properties of Web Authentication

While W3C Web Authentication has been formally verified to uphold its security properties of preventing phishing and “man in the middle” attacks, W3C Web Authentication also claims that authentication is unlinkable between origins, and we now seek to formally verify this property.

6.3.1 Threat Model

Traditionally cryptographic protocols have been required to satisfy secrecy (preventing phishing) and authentication (preventing “man in the middle”) properties. These requirements are normally verified by modeling them as reachability problems, i.e. can an attacker reach the key material or authenticate as a user? Some properties such as privacy cannot easily be expressed using the traditional threat model of ProVerif. However, similar to key material in security, once sensitive information is leaked, the identity of a user may be revealed. The threat model for the privacy properties is a malicious or honest but curious server whose goal is to uniquely identify a user, which is not a network attacker, but a Web attacker [24]. The goal of the Web attacker is to identify the user across domains using techniques like cookies to track the user. The goal of new web standards is to avoid accidentally introducing a new “super-cookie” by accident that lets even non-malicious servers track users across origins.

6.3.2 Security Goals

Privacy is difficult to formalize insofar as privacy is a holistic concept and may mean different things in different scenarios. Typically, privacy is defined as unlinkability, where given “two or more items of interest” that “these items of interest are no more and no less related after [the attacker’s] observation than they are related concerning his a priori knowledge” [25]. In terms of the same origin policy, this means that for any authentication event using Web Authentication within a given origin, the user should not be related in anyway to another event using Web Authentication at another origin. In terms of unlinkability, a user being unlinkable in relationship to other users creates an anonymity set as regards a group of users and a given action like authentication. As put by Pfitzmann, given that “anonymity is the state of being not identifiable within a set of subjects, the anonymity set,” various technologies to maintain privacy may be considered better than others insofar as they provide larger anonymity sets. However, for purposes of our formal verification, we will not use anonymity sets, but simply see if a user can be linked at all between two authentication events.

6.3.3 ProVerif Description

Unlike security properties, there is not a clear way to model privacy properties in ProVerif. One approach is to compare an ideal flow of the protocol from one that instantiates concrete values, so that privacy violations can be inferred if a difference between the ideal and the instantiated flow can be detected [26]. However, the problem with this approach is that it assumes that the attacker is a network attacker observing the secure channel (such as the TLS connection), not a party in the protocol such as the server. One simple option of modeling the server itself as malicious could have the server drop all data to the clear, but this would not accurately model a protocol that inadvertently allows some data to be shared between non-malicious servers on different origins due to the design of the protocol itself.

16 Deliverable D4.2 NEXTLEAP Grant No. 688722

In order to model privacy in terms of the protocol itself violating the same origin property in ProVerif, we used a reachability event. For a two-party protocol, a unique identification of a user simply requires that between two sessions of the same program the same user can be identified via reaching an event that connects two different registration or authentication events in the protocol. In order to test unlinkability in Web Authentication, we add to the server the ability to create a database of keys using ProVerif’s table constructor. For each registration phase, the servers checks its database of attestation keys and tries to determine if the same attestation key has been used before. If it has, the user is re-identified by virtue of using the same attestation key and the unlinkability property is broken. For example, this is the case when the same user tries to create two different accounts with different credential keys but using the same authenticator (if the authenticator has a single attestation key).

In ProVerif, we model privacy as the event reachSameKey, where we store key materials such as attestation keys (Att pkU ) for a given user U in a table. Then we can show that when the model is ran over an unbounded number of session, the same key material can be reached across multiple sessions, allowing the attestation key material to be used as an identifier for a user across origins.

get tableAttPk(attpkU) in event reachSamekey(attpkU) else insert tableAttPk(attpkU);

ProVerif proved that reachSameKey can be reached across multiple sessions of the protocol.7 The problem is that the W3C Web Authentication protocol sends in the registration phase an attestation public key and the initial attestation credential is signed by the attestation private key. The server simply has to store these attestation public keys and check to see if an attestation key already exists in its database when a user attempts to register to the server. If the attestation key is already in the database, the user is reidentified by their re-use of the same authenticator. Note that keys are not required by this attack on privacy, as any authenticator-specific identifier would allow the attack to be done.

7 Results and Next Steps

We modeled both the security and privacy properties of W3C Web Authentication, and proven (assuming TLS usage) that the user can authenticate securely using cryptographic key material as their key material can not be violated by a network-level attacker. However, if we assume that the server is either “honest but curious” or malicious, the privacy property of unlinkability between origins can be violated. In this second scenario, the server is trying to identify that the same user is behind two accounts even though he is using two different public credential keys. The server creates a database and saves the attestation public key during the registration phase. When the same user is registering their authenticator for the second time and tries to create an account with another credential public key, the server checks the database and identifies that it’s the same user as the new user registered the same authenticator as a previous user. This scenario can be expanded if two servers are co-operating. In this case, the first server (on one origin) can share the attestation key of the device with a second server controlling a different origin than the first server. Then, when a user that has already registered their authenticator at the first server begins to register their authenticator on to the second server, the second server can identify the user across origins. Therefore, the privacy properties of W3C Web Authentication do not hold unless there is a modification to the authenticator’s attestation keys cannot be linked across origins with a user identity. The specification does note that no attestation may be used and that basic attestation should have keys where “authenticators of the same model often share the same attestation key pair” [14], but this is not enforced. The idea of an “Anonymization CA” that “can dynamically generate per-origin attestation keys and attestation certificates” is mentioned but “the envisioned functionality of an Anonymization CA is not firmly established” [14].

7The full ProVerif output for the attacks on both models are available from https://github.com/hhalpin/webauthn-model.

17 Deliverable D4.2 NEXTLEAP Grant No. 688722

There are three options that W3C Web Authentication currently discusses, although these methods are not given as mandatory in the W3C draft Recommendation. In detail:

In self-attestation, the authenticator “uses the credential private key to create the attestation signature”and • so “the authenticator has no distinct attestation key pair nor attestation certificate” [14], allowing the attestation not to convey any new property about the authenticator and so would preserve the user’s unlinkability across origins.

Even under basic authentication, it is possible that “authenticators of the same model often share the same • attestation key pair” [14]. Therefore, rather than uniquely identifying a user, the use of the attestation key likely will reduce their anonymity set.

The authenticator has an “authenticator-specific (endorsement) key” that is “used to securely communicate • with a trusted third party, the Attestation CA” [14]. However, this would reduce the anonymity set of the user and also has the unfortunate side-effect of introducing a trusted third-party into the system that can then vouch for any details of the authenticator. The main advantage of the CA is that rather than per model keys, possibly per brand keys could be used that would increase the anonymity set, i.e. all Yubikeys could use Yubico as their trusted Privacy CA, producing a larger anonymity set.

With elliptic curve direct anonymous attestation (ECDAA), an anonymous authentication credential is used • to blindly sign the attestation credentials. The use of “blinding avoids the DAA credentials being misused as global correlation handle” [14] and so keeps the user’s attestation action private from the CA itself.

ECDAA is a variant of Direct Anonymous Attestation (DAA) that uses elliptic curves rather than the RSA keys typically used in DAA [27]. Of all the schemes suggested by the W3C Web Authentication Protocol [14], the most promising in terms of privacy is ECDAA, so we will explore ECDAA as it is the best mitigation available currently for the privacy problem of W3C Web Authentication. The DAA [28] protocol satisfies privacy whenever a process where Alice interacts with the verifier is observationally equivalent (to an attacker whose goal is identify users) to when Bob interacts with the verifier. This is the only technique that guarantees the identity of the user are not revealed to a third party (such as in the attestation CA case) and the attestation of the authenticator can be transmitted to a server without linking it across origins or to the third party issuer.

7.1 ECDAA

DAA (and ECDAA) allows the remote attestation of an authenticator to a server while preserving the privacy of user, unlike the normal case of an attestation CA. The goal is that a user can have the capabilities of their authenticator attested while protecting their identity from a third-party server, called the issuer, that generates the attestation credentials. The server must only learn that their authenticator is trusted and not which particular authenticator is being used, and therefore it would preserve the same origin policy restriction of W3C Web Authentication. The DAA protocol can be viewed as a group signature scheme without the ability to revoke anonymity. In broad terms, the authenticator contacts the issuer of attestation credentials (such as their device manufacturer) for their device and requests membership to a group. If the issuer wishes to accept the request, it grants the authenticator an attestation credential. The host is now able to anonymously authenticate itself as a group member to a server, and the server can act as a verifier with respect to its attestation credential. This protocol is initiated when an authenticator wishes to obtain an anonymous authentication credential and so must take place before the registration and authentication phases of W3C Web Authentication.

1. The authenticator creates a secret f and a blinding factor v0 and it constructs a blinding message U = blind( f ,v0).

2. The issuer creates a nonce ne. 3. The authenticator receives the nonce in an encrypted message, decrypts it and returns hash(U n ). || e 4. The issuer confirms that the hash is correctly formed.

18 Deliverable D4.2 NEXTLEAP Grant No. 688722

5. The issuer generate a nonce ni and sends to the authenticator.

6. The authenticator constructs a proof of knowledge that the messages U and ni are correct. 7. The issuer verifies the proof and generates a blind signature on the message U

8. The authenticator verifies the issuer’s signature and proof and unblinds the signature, revealing a secret credential v (the signed f ).

Once the authenticator has the anonymous attestation credential from the issuer, it can produce a proof of knowledge of a signature on the message sent by the server and therefore proves that the authenticator has a valid attestation from the issuer. This technique has been formally verified in the DAA case using ProVerif [28], although the formalization of the elliptic curve-variant remains future work.

Note that signature of the issuer reduces the anonymity set, as the issuer reveals “per brand” identity, and from the standpoint of the RP, the anonymity set could be the same as an attestation CA. What is likely needed for future versions of the W3C Web Authentication API, in particular on anonymization CAs, is a move to finer granularity of attributes, such as the support of simply revealing the particular attributes of authenticators. Regardless of the scheme in W3C Web Authentication used to mitigate the attack, the attestation public key and attestation certificate on registration in W3C Web Authentication still reduces the anonymity set considerably and increases the chances of linking a user across origins. Therefore, future research should engage with attribute-based credentials and forms of unlinkable credentials that have better privacy properties than DAA-based schemes [29].

8 Conclusion

While we have started to formally verify that the W3C Web Authentication protocol is secure and so ensures strong user authentication, the W3C Web Authentication API allows violations of the privacy of users that undermine the stated goals of the protocol in terms of unlinkability of users between origins, unless suggested functionality is made to be mandatory. The solution is to require more detailed and mandatory privacy protections in the protocol itself, such as having the authenticator generate dynamically an attestation public key that is specific to each origin where an identifier guarantees the type of authenticator (rather than a separate key) or use cryptographic techniques such as ECDAA or zero-knowledge proofs that are more privacy-preserving than any of the options recommended in the W3C Web Authentication protocol [29]. Future work should formalize more completely ECDAA with W3C Web Authentication and the other options in the specification. In general, our model makes a number of simplifications and so much work is needed to formally model the complete protocol as given in the W3C specification, and so this model should be considered a beginning that can be subject to review by the W3C Working Group rather than the end of analysis.

Although security properties are fairly straightforward to prove, privacy properties are more difficult to formalize, and future research should find better formalizations that fit within both symbolic and computational formal verification tools, with a focus on common privacy boundaries such as the same origin policy for the Web. This would allow multiple protocols from web browsers that should maintain the same origin policy, such as the currently unverified WebRTC protocol and verified (although not in terms of privacy properties) W3C Web Cryptography API [10], to be easily verified using the same tool-set. Likely a modular approach to formally verifying the security and privacy properties of web applications could eventually be accomplished, as these web applications depend on combinations of these and protocols. More work needs to be done to model the same origin policy in ProVerif even for W3C Web Authentication, in order to develop a standard way of verifying privacy across Web APIs. More comprehensive ways of modeling privacy beyond reachability should be applied and extended to cover the same origin policy [26], although we are the first to our knowledge to model privacy via the same origin policy as distinct from network attackers in a formally verified Web API.

In the future, all protocols should go through a rigorous process of formal verification in order to determine their security and privacy properties before standardization. This would have a number of effects that are beneficial to protocol design. Tools such as ProVerif are specialized in security and privacy properties, and so can be 19 Deliverable D4.2 NEXTLEAP Grant No. 688722 deployed at the very beginning of the design phase of new protocols before or at the beginning of standardization. The widespread use of formal verification would not only increase security and privacy, but would allow the process of standardization to be less dependent on human reputation or the influence of powerful implementers, as has been claimed to be the case with controversial standards around DRM like the W3C Encrypted Media Extensions standard [30]. The process of the standardization should be moved from being a social process to a scientific process, where the security and privacy of standard protocols can be proven via automated formal verification, with proofs subject to public review. The scientific analysis of security and privacy in standards via formal verification presents an exciting frontier in the science of security.

References

[1] S. Goldwasser and S. Micali, “Probabilistic encryption,” Journal of computer and system sciences, vol. 28, no. 2, pp. 270–299, 1984.

[2] R. M. Needham and M. D. Schroeder, “Using encryption for authentication in large networks of computers,” Communications of the ACM, vol. 21, no. 12, pp. 993–999, 1978.

[3] G. Lowe, “Breaking and fixing the needham-schroeder public-key protocol using fdr,” in International Work- shop on Tools and Algorithms for the Construction and Analysis of Systems. Springer, 1996, pp. 147–166.

[4] K. Bhargavan, A. D. Lavaud, C. Fournet, A. Pironti, and P. Y. Strub, “Triple handshakes and cookie cutters: Breaking and fixing authentication over TLS,” in Security and Privacy (SP), 2014 IEEE Symposium on. IEEE, 2014, pp. 98–113.

[5] N. Swamy, J. Chen, C. Fournet, P. Strub, K. Bhargavan, and J. Yang, “Secure distributed programming with value-dependent types,” in Proceeding of the 16th ACM SIGPLAN international conference on Functional Programming, 2011, pp. 266–278.

[6] B. Blanchet, B. Smyth, and V. Cheval, “Proverif 1.90: Automatic cryptographic protocol verifier, user manual and tutorial,” 2015.

[7] B. Blanchet, “Cryptoverif: Computationally sound mechanized prover for cryptographic protocols,” in Dagstuhl seminar “Formal Protocol Verification Applied, 2007, p. 117.

[8] J. B. Almeida, M. Barbosa, G. Barthe, and F. Dupressoir, “Verifiable side-channel security of cryptographic implementations: Constant-time MEE-CBC,” in Fast Software Encryption - 23rd International Conference, FSE 2016, Bochum, Germany, March 20-23, 2016, Revised Selected Papers, ser. Lecture Notes in Computer Science, T. Peyrin, Ed., vol. 9783. Springer, 2016, pp. 163–184.

[9] J. Protzenko, J.-K. Zinzindohoue,´ A. Rastogi, T. Ramananandro, P. Wang, S. Zanella-Beguelin,´ A. Delignat- Lavaud, C. Hrit¸cu, K. Bhargavan, C. Fournet et al., “Verified low-level programming embedded in f,” Proceed- ings of the ACM on Programming Languages, vol. 1, no. ICFP, p. 17, 2017.

[10] K. Cairns, H. Halpin, and G. Steel, “Security analysis of the w3c web cryptography ,” in Security Standardisation Research. Springer, 2016, pp. 112–140.

[11] K. Bhargavan, B. Blanchet, and N. Kobeissi, “Verified models and reference implementations for the tls 1.3 standard candidate,” in IEEE Symposium on Security and Privacy (Oakland), 2016.

[12] A. Das, J. Bonneau, M. Caesar, N. Borisov, and X. Wang, “The tangled web of password reuse.” in NDSS, vol. 14, 2014, pp. 23–26.

[13] H. Halpin, “Web authentication: The next step in the evolving identity eco-system?” in Proceedings of the IEEE CS Security and Privacy Workshops, 2012.

20 Deliverable D4.2 NEXTLEAP Grant No. 688722

[14] B. Vijay, H. Le Van Gong, D. Balfanz, A. Czeskis, A. Birgisson, J. Hodges, M. Jones, R. Linde- man, and J. Jones, “Web authentication: An api for accessing public key credentials level 1,” 2017, https://www.w3.org/TR/webauthn/.

[15] A. Czeskis, M. Dietz, T. Kohno, D. Wallach, and D. Balfanz, “Strengthening user authentication through opportunistic cryptographic identity assertions,” in Proceedings of the 2012 ACM conference on Computer and communications security. ACM, 2012, pp. 404–414.

[16] S. Srinivas, D. Balfanz, and E. Tiffany, “Universal 2nd factor (u2f) overview,” FIDO Alliance Proposed Standard, 2015.

[17] B. Vijay, H. Le Van Gong, D. Balfanz, A. Czeskis, A. Birgisson, and J. Hodges, “Fido 2.0: Web api for accessing fido 2.0 credentials,” 2015, https://www.w3.org/Submission/2015/SUBM-fido-web-api-20151120/.

[18] O. Pereira, F. Rochet, and C. Wiedling, “Formal analysis of the fido 1. x protocol,” in International Symposium on Foundations and Practice of Security. Springer, 2017, pp. 68–82.

[19] S. R. V. Saravanan Subramanian, “Web security: Same origin policy and its exemptions,” 2006.

[20] D. Balfanz, A. Langley, N. Harper, and J. Hodges, “Token binding over http,” IETF, 2017, https://datatracker.ietf.org/doc/draft-ietf-tokbind-https.

[21] D. Dolev and A. Yao, “On the security of public key protocols,” Information Theory, IEEE Transactions on, vol. 29, no. 2, pp. 198 – 208, Mar. 1983.

[22] B. Blanchet et al., “Modeling and verifying security protocols with the applied pi calculus and proverif,” Foundations and Trends R in Privacy and Security, vol. 1, no. 1-2, pp. 1–135, 2016.

[23] M. Abadi and C. Fournet, “Mobile values, new names, and secure communication,” in ACM SIGPLAN Notices, vol. 36, no. 3. ACM, 2001, pp. 104–115.

[24] D. Akhawe, A. Barth, P. E. Lam, J. Mitchell, and D. Song, “Towards a formal foundation of web security,” in Computer Security Foundations Symposium (CSF), 2010 23rd IEEE. IEEE, 2010, pp. 290–304.

[25] A. Pfitzmann and M. Hansen, “Anonymity, unlinkability, unobservability, pseudonymity, and identity management-a consolidated proposal for terminology,” 2005.

[26] L. Hirschi, D. Baelde, and S. Delaune, “A method for verifying privacy-type properties: the unbounded case,” in Security and Privacy (SP), 2016 IEEE Symposium on. IEEE, 2016, pp. 564–581.

[27] L. Chen, D. Page, and N. P. Smart, “On the design and implementation of an efficient daa scheme,” in International Conference on Smart Card Research and Advanced Applications. Springer, 2010, pp. 223–237.

[28] S. Delaune, M. Ryan, and B. Smyth, “Automatic verification of privacy properties in the applied pi calculus,” Trust Management II, pp. 263–278, 2008.

[29] J. Hajny and L. Malina, “Unlinkable attribute-based credentials with practical revocation on smart-cards,” in International Conference on Smart Card Research and Advanced Applications. Springer, 2012, pp. 62–76.

[30] H. Halpin, “The crisis of standardizing drm: The case of w3c encrypted media extensions,” in International Conference on Security, Privacy, and Applied Cryptography Engineering. Springer, 2017, pp. 10–29.

21 D4.2 NEXTLEAP Grant No. 688722

3 Signal Protocol (Synchronous Messaging)

22 Deliverable D4.2 NEXTLEAP Grant No. 688722

1 Introduction

Designing new cryptographic protocols is highly error-prone; even well-studied protocols, such as Transport Layer Security (TLS), have been shown to contain serious protocol flaws found years after their deployment (see e.g. [1]). Despite these dangers, modern web applications often embed custom cryptographic protocols that evolve with each release. The design goal of these protocols is typically to protect user data as it is exchanged over the web and synchronised across devices, while optimizing performance for application-specific messaging patterns and deployment constraints. Such custom protocols deserve close scrutiny, but their formal security analysis faces several challenges.

First, web applications often evolve incrementally in an ad hoc manner, so the embedded cryptographic protocol is only ever fully documented in source code. Even when protocol designers or security researchers take the time to create a clear specification or formal model for the protocol, these documents are typically incomplete and quickly go out-of-date. Finally, even if the protocol itself is proved to be secure, bugs in its implementation can often bypass the intended security guarantees. Hence, it is not only important to extract a model of the protocol from the source code and analyze its security, it is essential to do so in a way that the model can evolve as the application is modified.

In this paper, we study the protocol underlying the Signal messaging application developed by Open Whisper Systems. Variants of this protocol have also been deployed within WhatsApp, Facebook Messenger, Viber, and many other popular applications, reaching over a billion devices. The protocol has been known by other names in the past, including Axolotl, TextSecure (versions 1, 2, and 3), and it continues to evolve within the Signal application under the name Signal Protocol. Until recently, the main documentation for the protocol was its source code, but new specifications for key components of the protocol have now been publicly released.1

Signal Protocol has ambitious security goals; it enables asynchronous (zero round-trip) authenticated messaging between users with end-to-end confidentiality. Each message is kept secret even if the messaging server is compromised, and even if the user’s long term keys are compromised, as long as these keys are not used by the attacker before the target message is sent (forward and future secrecy.) To achieve these goals, Signal uses a novel authenticated key exchange protocol (based on mixing multiple Diffie-Hellman shared secrets) and a key refresh mechanism (called double ratcheting). The design of these core mechanisms in TextSecure version 2 was cryptographically analyzed in [2] but the protocol has evolved since then and the security of Signal as it is currently implemented and deployed remains an open question.

In fact, although they all implement the same core protocol, different implementations of the Signal protocol vary in important details, such as how users are identified and authenticated, how messages are synchronised across devices, etc. We seek to develop and analyze one such variant that was recently incorporated into Cryptocat, a desktop messaging application developed by one of the current authors. We call this variant SP in the rest of this paper. We develop a detailed model for SP in the applied pi calculus and verify it using the ProVerif protocol analyzer [3] for these security goals against adversaries in a classic Dolev-Yao model [4]. We also develop a computational proof for SP using the CryptoVerif prover [5]. There remains the challenge of keeping our models up-to-date as the protocol code evolves within Cryptocat. To this end, we design a model extraction tool that can compile the protocol source code to the applied pi calculus.

Signal has been implemented in various programming languages, but most desktop implementations of Signal, including Cryptocat, are written in JavaScript. Although JavaScript is convenient for widespread deployability, it is not an ideal language for writing security-critical applications. Its permissive, loose typing allows for dangerous implementation bugs and provides little isolation between verified cryptographic protocol code and unverified third-party components. Rather than trying to verify general JavaScript programs, we advocate that security- critical components like SP should be written in a well-behaved subset that enables formal analysis.

We introduce ProScript (short for “Protocol Script”), a programming and verification framework tailored specifi- cally for the implementation of cryptographic protocols. ProScript extends Defensive JavaScript (DJS) [6, 7], a

1https://whispersystems.org/docs/specifications/x3dh/

23 Deliverable D4.2 NEXTLEAP Grant No. 688722 static type system for JavaScript that was originally developed to protect security-critical code against untrusted code running in the same origin. ProScript is syntactically a subset of JavaScript, but it imposes a strong coding discipline that ensures that the resulting code is amenable to formal analysis. ProScript programs are mostly self-contained; they cannot call arbitrary third-party libraries, but are given access to carefully implemented (well-typed) libraries such as the ProScript cryptographic library (PSCL). Protocols written in ProScript can be type-checked and then automatically translated into an applied pi calculus [8] model using the ProScript com- piler. The resulting model can be analyzed directly through ProVerif and can be adapted and extended to a proof in CryptoVerif. As the code evolves, this model can be automatically refreshed to enable new analyses and proofs, if necessary.

Contributions. We present an outline of our contributions in this paper:

A Security Model and New Attacks. We present security goals and a threat model for secure messaging ( 2). § As a motivation for our verification approach, we discuss protocol weaknesses and implementation bugs in the messaging protocol underlying the popular Telegram application.

Automated Model Extraction from JavaScript. We present the ProScript compiler, which allows for the compi- lation from a subset of JavaScript into a readable protocol model in the applied pi calculus ( 4). Model extraction § enables formal verification to keep up with rapidly changing source code. Readable models allow the protocol analyst to experiment with different threat models and security goals and to test new features before including them in the implementation.

A Symbolic Security Analysis of SP. We formalize and analyze a variant of Signal Protocol for a series of security goals, including confidentiality, authenticity, forward secrecy and future secrecy, against a classic symbolic adversary ( 5). Our analysis uncovers several weaknesses, including previously unreported replay § and key compromise impersonation attacks, and we propose and implement fixes which we then also verify.

A Computational Cryptographic Proof for SP. We present proofs of message authenticity, secrecy and forward secrecy for SP obtained using the CryptoVerif computational model prover [5]. ( 6) § A Verified Protocol Core for Cryptocat. We integrate our verified protocol code into the latest version of Cryp- tocat2 ( 7), a popular open source messaging client with thousands of users that is developed and maintained § by one of the authors of this paper. We show how the new architecture of Cryptocat serves to protect the verified protocol code from bugs in the rest of the application.

2 A Security Model for Encrypted Messaging

We consider a simple messaging API as depicted below. An initiator A can start a conversation with B by calling startSession with long-term secrets for A and any identity credentials it has for B. This function returns the initial conversation state T0. Thereafter, the initiator can call send with a plaintext message M1 to obtain the encrypted message E1 that it needs to send on the network. Or it can call recv with an encrypted message E2 it received (supposedly from B) to obtain the plaintext message M2. ab T0 = startSession(secretsA,identityB) ab ab T1 ,E1 = send(T0 ,M1) ab ab T2 ,M2 = recv(T1 ,E2)

The responder B uses a similar API to accept sessions and receive and send messages:

ba T0 = acceptSession(secretsB,identityA) ba ba T1 ,M1 = recv(T0 ,E1) ba ba T2 ,E2 = send(T1 ,M2)

2https://crypto.cat

24 Deliverable D4.2 NEXTLEAP Grant No. 688722

We deliberately chose a functional state-passing API with no side-effects in order to focus on cryptographic protocol computations, rather than the concrete details of how these messages are sent over the network.

2.1 Threat Model

While threat models vary for different protocols, we consider the following threats in this paper:

Untrusted Network We assume that the attacker controls the network and so can intercept, tamper with and • inject network messages (e.g. E1,E2). Moreover, if two messaging clients communicate via a server, we typically treat that server as untrusted.

Malicious Principals The attacker controls a set of valid protocol participants (e.g. M), for whom it knows • the long-term secrets. The attacker may advertise any identity key for its controlled principals; it may even pretend to own someone else’s identity keys.

Long-term Key Compromise The attacker may compromise a particular principal (e.g. A) during or after the • protocol, to obtain her long-term secrets.

Session State Compromise The attacker may compromise a principal to obtain the full session state at some • ab intermediate stage of the protocol (e.g. T1 ).

2.2 Cryptographic Models

Traditionally, symbolic cryptographic models have been particularly suitable for automated protocol analysis. They ignore attacks with negligible probability and assume that each cryptographic function is a perfect black- box. For example, in such models, hash functions never collide and encryption is a message constructor that can only be reversed by decryption. In the computational model, cryptographic primitives are functions over bitstrings and their security is specified in terms of probabilities. These models are more precise and closer to those used by cryptographers, but usually do not lend themselves to fully automated proofs. Generally, we will use symbolic models when we are trying to find attacks that rely on logical flaws in the protocol and in its use of cryptographic primitives. We will use computational models when we want to build a cryptographic proof of security, starting from standard cryptographic assumptions.

2.3 Security Goals

We state a series of semi-formal security goals in terms of our generic messaging API. We use the phrase “A sends a message M to B” to mean that A calls Send(T,M) with a session state T that represents a conversation between A and B. Similarly, we say that “B receives a message M from A” to mean that B obtained M as a result of calling Recv(T,E) with a session T with A.

Unless otherwise specified, the following security properties assume that both A and B are honest, that is, their long-term secrets have not been compromised. We begin with several variants of authenticity goals:

Message Authenticity If B receives a message M from A, then A must have sent M to B. • No Replays Each message received by B from A corresponds to a unique message sent by A. That is, the • attacker must not be able to get a single message sent by A to be accepted twice at B.

No Key Compromise Impersonation Even if the long-term secrets of B are compromised, message authen- • ticity must hold at B. That is, the attacker must not be able to forge a message from A to B.

Our definition of message authenticity covers integrity as well as sender and recipient authentication. Obtaining message authenticity also helps prevent unknown key share attacks, where B receives a message M from A, but A sent that message to a different intended recipient C. We define four confidentiality goals: 25 Deliverable D4.2 NEXTLEAP Grant No. 688722

Secrecy If A sends some secret message M to B, then nobody except A and B can obtain M. • Indistinguishability If A randomly chooses between two messages M ,M (of the same size) and sends • 0 1 one of them to B, the attacker cannot distinguish (within the constraints of the cryptographic model) which message was sent.

Forward Secrecy If A sends a secret message M to B and if A’s and B’s long-term secrets are subsequently • compromised, the message M remains secret.

Future Secrecy Suppose A sends M in a session state T , then receives N, then sends M . If the session • 0 state T is subsequently compromised, the message M0 remains secret. Some protocols satisfy a weaker notion of forward secrecy, sometimes called weak forward secrecy, where an attacker is not allowed to actively tamper with the protocol until they have compromised the long-term keys [9]. Some messaging protocols also seek to satisfy more specific authenticity and confidentiality goals, such as non-repudiation and plausible deniability. We will ignore them in this paper.

In the next section, we evaluate two secure messaging applications against these goals, we find that they fail some of these goals due to subtle implementation bugs and protocol flaws. Hence, we advocate the use of automated verification tools to find such attacks and to prevent their occurrence.

3 Analyzing Real-World Messaging Protocols

Modern messaging and transport protocols share several distinctive features [10]: for example, Signal Protocol, SCIMP, QUIC and TLS 1.3 share a strong focus on asynchronous key agreement with a minimum of round trips. Some also guarantee new security goals such as future secrecy. The protocols also assume non-standard (but arguably more user-friendly) authentication infrastructures such as Trust-on-First-Use (TOFU). Modern messag- ing protocols have several interesting features and properties that set them apart from classic cryptographic protocols and upon which we focus our formal verification efforts:

New Messaging Patterns. In contrast to connection-oriented protocols, modern cryptographic protocols are constrained by new communication flows such as zero-round-trip connections and asynchronous messaging, where the peer may not even be present.

Confidentiality Against Strong Adversaries. protocols need to be robust against server compromise and device theft and so seek to provide strong and novel forward secrecy guarantees.

Weak Authentication Frameworks. Many of these protocols do not rely on public key infrastructures. Instead they may authenticate peers on a TOFU basis or even let peers remain anonymous, authenticating only the shared connection parameters.

Code First, Specify Later. Unlike Internet protocols, which are designed in committee, these protocols are first deployed in code and hand-tuned for performance on a particular platform. The code often remains the definitive protocol specification.

Before outlining our verification approach for such protocols, we take a closer look at two messaging applications: Telegram and Cryptocat.

3.1 Secret Chats in Telegram

Our first example is the “MTProto” [11] secure messaging protocol used in the Telegram messaging application. We focus on the “secret chat” feature that allows two Telegram clients who have already authenticated them- selves to the server to start an encrypted conversation with each other. Although all messages pass through the Telegram server, the server is untrusted and should not be able to decrypt these messages. The two clients A 26 Deliverable D4.2 NEXTLEAP Grant No. 688722

Client Server Client A DHConfig(p,g) S DHConfig(p,g) B

Checks(p,g) Checks(p,g) Generates (a,ga) Request(A,B,ga)

Checks ga 0,1, 1 6∈ { − } Generates (b,gb) Accept(B,A,gb)

Checks gb 0,1, 1 Does not know gab,k Computes k = kdf(gab) 6∈ { − } Computes k = kdf(gab) Confirm(A,B,hash(gab)) Confirm(B,A,hash(gab)) SecretChat(A,B,enck(m)) k SecretChat(B,A,enc (m0))

Figure 1: Telegram’s MTProto Protocol for Secret Chats. and B download Diffie-Hellman parameters from the Telegram server and then generate and send their public values to each other.

The key exchange is not authenticated with long-term credentials. Instead, the two clients are expected to com- municate out-of-band and compare a SHA-1 hash (truncated to 128-bits) of the Diffie-Hellman shared secret. If two users perform this authentication step, the protocol promises that messages between them are authentic, confidential, and forward secret, even if the Telegram server is compromised. However this guarantee cru- cially relies on several cryptographic assumptions, which may be broken either due to implementation bugs or computationally powerful adversaries, as we describe below.

Malicious Primes. MTProto relies on clients checking that the Diffie-Hellman configuration (p,g) that they received from the server is suitable for cryptographic use. The specification requires that p be a large safe prime; hence the client must check that it has exactly 2048 bits and that both p and (p 1)/2 are prime, using − 15 rounds of the Miller-Rabin primality test. There are several problems with this check. First, the server may be able to carefully craft a non-prime that passes 15 rounds of Miller-Rabin. Second, checking primality is not enough to guarantee that the discrete log problem will be hard. If the prime is chosen such that it has “low weight”, the SNFS algorithm applies, making discrete logs significantly more practical [12]. Even if we accept that primality checking may be adequate, it is unnecessary for an application like Telegram, which could simply mandate the use of well-known large primes instead [13].

Public Values in Small Subgroups. A man-in-the-middle can send to both A and B public Diffie-Hellman values gb and ga equal to 1 (resp. 0, resp. p 1). Both A and B would then compute the shared secret as gab = 1 (resp. − 0, resp. 1 or 1). Since their key hashes match, A and B think they have a confidential channel. However, the − attacker can read and tamper with all of their messages. More generally, MTProto relies on both peers verifying that the received Diffie-Hellman public values do not fall in small subgroups. This check is adequate to prevent the above attack but could be made unnecessary if the two public values were to be authenticated along with the shared secret in the hash compared by the two peers.

Implementation Bugs in Telegram for Windows. The above two weaknesses, reported for the first time in

27 Deliverable D4.2 NEXTLEAP Grant No. 688722 this paper, can result in attacks if the protocol is not implemented correctly. We inspected the source code for Telegram on different platforms; while most versions perform the required checks, we found that the source code for Telegram for Windows Phone did not check the size of the received prime, nor did it validate the received Diffie-Hellman values against 1, 0 or p 1. We reported both bugs to the developers, who acknowledged them − and awarded us a bug bounty.

Such bugs and their consequent attacks are due to missed security-relevant checks, and they can be found automatically by symbolic analysis. For example, [14] shows how to model unsafe (malicious) primes and invalid public keys in ProVerif and uses this model to find vulnerabilities in several protocols that fail to validate Diffie- Hellman groups or public keys.

Other Cryptographic Weaknesses. MTProto is also known to be vulnerable to an authentication attack if an adversary can compute 264 SHA-1 hashes [15], and to chosen-ciphertext attacks on its unusual AES-IGE encryption scheme [16]. How can we be sure that there are no other protocol flaws or implementation bugs hiding in MTProto? Any such guarantee would require a systematic security analysis of both the protocol and the source code against both symbolic and computational adversaries.

3.2 A New Protocol for Cryptocat

Cryptocat is a secure messaging application that is written in JavaScript and deployed as a desktop web appli- cation. Earlier versions of Cryptocat implement a variant of the OTR (Off-The-Record) messaging protocol [17] which suffers from several shortcomings. It does not support asynchronous messaging, so both peers have to be online to be able to message each other. It does not support multiple devices or encrypted file transfer. OTR also uses legacy cryptographic constructions like DSA signatures and prime-field Diffie-Hellman, which are slower and less secure than more modern alternatives based on elliptic curves. Furthermore, Cryptocat peers did not have long-term identities and so the authentication guarantees are weak. Early version of Cryptocat suffered from many high-profile implementation bugs, including the reuse of initialization vectors for file encryption [18], bad random number generation, and a classic JavaScript type flaw that resulted in a private key of 255 bits being coerced into a string that held only 55 bits. Some of these implementation flaws would have been found using a static type checker, others required deeper analysis.

Cryptocat was recently rewritten from scratch to upgrade both its messaging protocol and its implementation. The goal of this redesign was to isolate its protocol core and replace it with a verified messaging protocol written in a statically typed subset of JavaScript.

3.3 Towards Automated Verification

The innovative designs and unusual security guarantees of secure messaging protocols demand formal security analysis. Hand-written models with detailed cryptographic proofs can be useful as a reference, but we observe that the most recent analysis of Signal Protocol [2] is already out of date, as the protocols have moved on to new versions. Furthermore, manual cryptographic proofs often leave out details of the protocol for simplicity and some of these details (e.g. client authentication) may lead to new attacks. In this paper, we advocate the use of automated verification tools to enable the analysis of complex protocols as they evolve and incorporate new features. Moreover, we would also like to find protocol implementation bugs (like the ones in previous versions of Telegram and Cryptocat) automatically.

We advocate the verification approach depicted in Figure 2. The messaging application is written in JavaScript and is broken down into a cryptographic protocol core and untrusted application code that interact through a small well-typed API that hides all protocol secrets within the protocol core and only offers a simple send/receive functionality to the application. Notably, the protocol core is written in a domain-specific language and does not rely on any external libraries except for a well-vetted cryptographic library. The protocol code can be translated to

28 Deliverable D4.2 NEXTLEAP Grant No. 688722

Figure 2: Verification Approach. A ProVerif model is automatically extracted from ProScript protocol code and analyzed for its security goals against a symbolic attacker. The model is then edited by hand and extended with cryptographic assumptions and intermediate lemmas to build a computational proof that is verified by Cryp- toVerif. an applied pi calculus model and symbolically analyzed in ProVerif to find protocol flaws and attacks. The model can also be used as the starting point for a cryptographic proof for the protocol developed using CryptoVerif.

In the rest of this paper, we show how we applied this verification methodology to systematically analyze a variant of the Signal protocol, called SP, that is implemented in the new version of Cryptocat.

4 ProScript: A Language for Protocol Implementation

ProScript aims to be an ideal language for reliably implementing cryptographic protocols for web applications. Using ProScript, a protocol designer or implementer can implement a protocol, automatically extract a formal model from the code, verify the model using ProVerif, and then run the protocol code within a JavaScript . The ProScript framework does not target general JavaScript code, however existing applications can be adapted to use ProScript for their security-critical protocol components.

Our goal is to allow the developer to go back and forth between their protocol implementation and the ProVerif model, in order to help understand the behavior being illustrated, the properties being verified and how detected attacks, if any, relate to their source code. For these reasons, we pay special attention to generating models that are optimized both for verifiability as well as readability. This increases their utility to a human examiner who may wish to independently expand the model to include more specific process flows or to explore variations of the protocol against a manually defined adversary.

Syntactically, ProScript is a subset of JavaScript that can be naturally translated to the applied pi calculus. This restriction produces casualties, including recursion, for loops and extensible objects. A closer look at the ProScript syntax shows JavaScript employed in a particular style to bring out useful features:

Isolation. ProScript is based on Defensive JavaScript (DJS) [6, 7], a typed subset of JavaScript which focuses on protecting security-critical components from malicious JavaScript code running in the same environment. DJS imposes a strict typing discipline in order to eliminate language-based attacks like prototype poisoning. In particular, it forbids the use of unknown external libraries as well as calls to tamperable object methods such as .toString(). It also forbids extensible objects and arrays and prevents any access to object prototypes. These restrictions result in protocol implementations that are more robust and less influenced by the runtime environment. The ProScript typechecker builds on and extends DJS and hence, inherits both its language restrictions and isolation guarantees.

Type Declarations and Inference. ProScript requires all variables and functions to be declared before they are

29 Deliverable D4.2 NEXTLEAP Grant No. 688722 used, hence imposing a strict scoping discipline. For example, an expression v.x is well-typed if and only if v has been defined, as a local or global variable, to be an object with a property x. As an extension to the builtin types of DJS, ProScript allows type declarations for commonly used protocol data structures. For example, an array of 32 hexadecimal integers can be declared as a key type. The ProScript compiler recognizes such type declarations and uses them to translate the code into more concise and informative ProVerif models. Moreover, the typechecker can automatically infer fine-grained sub-types. For example, ProScript differentiates between numbers declared using decimal literals (ex. 128) and hexadecimal literals (ex. 0x80). Numbers defined using hexadecimal are sub-typed as bytes. This feature allows us to track how numerical values are employed in the protocol, and prevents type coercion bugs similar to an actual bug that we describe in 3.2, where a significant § loss of entropy was caused by a byte being coerced into a decimal value.

State-Passing Functional Style. ProScript’s syntax takes advantage of JavaScript’s functional programming features in order to encourage and facilitate purely functional protocol descriptions, which the compiler can translate into symbolically verifiable, human-readable models in the applied pi calculus. The functional style encourages the construction of state-passing functions, leaving state modification up to the unverified application outside of the ProScript code. The majority of a ProScript implementation tends to be a series of pure function declarations. A small subset of these functions is exposed to a global namespace for access by the verified application while most remain hidden as utility functions for purposes such as key derivation, decryption and so on. This state-passing style is in contrast to DJS that allows direct modification of heap data structures. The functional style of ProScript allows protocol data structures, including objects and arrays, to be translated to simple terms in ProVerif built using constructors and destructors, hence avoiding the state-space explosion inherent in the heap-based approach that is needed to translate DJS to ProVerif [7].

4.1 ProScript Syntax

A ProScript implementation consists of a series of modules, each containing a sequence of type declarations (containing constructors, assertion utilities, and type converters), constant declarations and function declara- tions.

Type Declarations. Types are declared as object constants with the name Type x where x is the name of the type (e.g. key). Type declaration objects include various properties:

1. construct, a function which returns the shape of the object and which is used to both define the type to the compiler and to instantiate new variables of this type throughout the code.

2. assert, a function allowing the ProScript compiler to infer that a function’s input parameter is of type x.

3. toBitstring, f romBitstring, conversion functions from type x to a regular string. These are detected by the ProScript compiler and represented as ProVerif type conversion functions in the extracted model.

4. clone, a function for cloning a variable of type x.

Constant Declarations. In ProScript, we prefer the use of constant declarations to variable declarations due to their decreased malleability. We also prohibit the reassignment of object properties because of the pointer-like behavior of JavaScript object variables rendering this difficult to model efficiently in ProVerif. Scoping is also enforced: ProScript only allows for the declaration of variables at the top of a module or function, preceding all function declarations or calls. Further, for an object v, we say that v.x is well-formed if and only if v has been declared, either as a type or scoped variable, to have a property x.

Function Declarations. The majority of a ProScript implementation tends to be a series of pure function decla- rations. A small subset of these functions is exposed to a global namespace for access by the verified application while most remain hidden as utility functions for purposes such as key derivation, decryption and so on. All Pro- Script functions are pure and state-passing, allowing them to be modeled into ProVerif functions, declared with the keyword letfun (See 4.2). All ProScript functions are typed and the ProScript compiler will enforce that they § 30 Deliverable D4.2 NEXTLEAP Grant No. 688722 are used with the same input types and return the same output type throughout the implementation. Top-level object declarations often contain function declarations. We assume for simplicity that these object declarations are flattened into top-level function declarations. In order to enforce type safety, ProScript objects and arrays are also non-extensible: JavaScript prototype functions such as Array.push cannot be employed and object accessors such as v[x] are disallowed. ProScript v ::= values x variables n numbers s strings true, false booleans undefined, null predefined constants e ::= expressions v values x : v ,...,x : v object literals { 1 1 n n} v.x field access [v1,...,vn] array literals v[n] array access Lib.l(v1,...,vn) library call f (v1,...,vn) function call σ ::= statements var x;σ variable declaration x = e;σ variable assignment const x = e;σ constant declaration if (v === v ) σ else σ if-then-else 1 2 { 1} { 2} return e return γ ::= globals const x = e constants const f = function(x ,...,x ) σ 1 n { } functions const Type_x = ... user types { } µ ::= γ0;...;γn modules

Note that we will use the defined Lib.l notation to access the ProScript Cryptography Library.

Operational Semantics. ProScript’s operational semantics is a subset of JavaScript, and both run on JavaScript interpreters. It is tooled based on the formal semantics of Maffeis et al. [19] and is superficially adapted for our language subset.

4.2 ProVerif Syntax

A ProVerif script Σ is divided into two major parts:

1. ∆1....∆n, a sequence of declarations which encapsulates all types, free names, queries, constructors, de- structors, equations, pure functions and processes. Queries define the security properties to prove. Destruc- tors and equations define the properties of cryptographic primitives.

2. P, the top-level process which then effectively employs ∆1....∆n as its toolkit for constructing a process flow for the protocol.

In processes, the replication !P represents an unbounded number of copies of P in parallel. Tables store persistent state: The process insert a(M1,...,Mn);P inserts the entry (M1,...,Mn) in table a, and runs P.

31 Deliverable D4.2 NEXTLEAP Grant No. 688722

The process get a(=M1,x2,...,xn) in P looks for an entry (N1,...,Nn) in table a such that N1 = M1. When such an entry is found, it binds x2,...,xn to N2,...,Nn respectively and runs P. Events are used for recording that certain actions happen (e.g. a message was sent or received), in order to use that information for defining security properties. Phases model a global synchronization: processes initially run in phase 0; then at some point processes of phase 0 stop and processes of phase 1 run and so on. For instance, the protocol may run in phase 0 and some keys may be compromised after the protocol run by giving them to the adversary in phase 1. ProVerif M ::= terms v values a names f (M1,...,Mn) function application E ::= enriched terms M return value new a : τ;E new name a of type τ let x = M in E variable definition if M = N then E1 else E2 if-then-else P,Q ::= processes 0 null process in(M,x : τ);P input x from channel M out(M,N);P output N on channel M let x = M in P variable definition P Q parallel composition | !P replication of P insert a(M1,...,Mn);P insert into table a get a(=M1,x2,...,xn) in P get table entry specified by M1 event M;P event M phase n;P enter phase n ∆ ::= declaration type τ type τ free a : τ name a query q query q table a(τ1,...,τn) table a fun C(τ1,...,τn) : τ constructor reduc forall x1 : τ1,...,xn : τn; f (M1,...,Mn) = M destructor equation forall x1 : τ1,...,xn : τn;M = M0 equation letfun f (x1 : τ1,...,xn : τn) = E pure function let p(x1 : τ1,...,xn : τn) = P process Σ ::= ∆1....∆n.process P script

4.3 Translation

Within Σ, ProScript functions are translated into ProVerif pure functions. Type declarations are translated into ProVerif type declarations. Individual values, such as strings and numbers, are declared as global constants at the top-level scope of the ProVerif model with identifiers that are then employed throughout the model when appropriate. Objects and Arrays are instantiated in the model using functions, with destructors automatically generated in order to act as getters.

32 Deliverable D4.2 NEXTLEAP Grant No. 688722

Translation Rules M ::= v x : v ,...,x : v [v ,...,v ] v | { 1 1 n n} | 1 n V M M Values to Terms v → V v = v V x : v ,...,x : v = Obj_t(v ,...,v ) J{ 1K 1 n n} 1 n V J[vK1,...,vn] = Arr_t(v1,...,vn) J K E e M Expressions to Terms J → K E Mv = V Mv EJv.Kx = get_x(v) EJv[i]K = get_iJ (Kv) EJLibK.l(v1,...,vn) = Lib_l(V v1 ,...,V vn ) EJ f (vK1,...,vn) = f (V v1 ,...,V vn ) J K J K J K S σ E Statements to Enriched Terms J → K J K J K S var x;σ = S σ SJx K= e;σ = let x = E e in S σ SJconst x K= e;σJ =K let x = E e in S σ SJreturn vK = V v J K J K S if (v === v ) σ else σ = J 1 K2 { 1} {J K2} J K Jif V v1K = V JvK2 then S σ1 else S σ2 J K F γ ∆ Types and Functions to Declarations →J K J K J K J K F const f = function(x ,...,x ) σ = 1 n { } JletfunK f (x1,...,xn) = S σ F const Type_t = ... = type t J { } K J K C µ (P) P Constants to Top-level Process J → K C ε (P) = P CJconstK x = e;µ (P) = let x = E e in C µ (P) J K M µ (P) Σ Modules to Scripts J → K J K J K M µ (P) = F γ1 ....F γn .C µc (P) whereJ K µc contains all globals const x = e in µ andJ γK1,..., γn areJ K the otherJ globalsK J K of µ.

Translation Soundness. We currently do not formally prove translation soundness, so proofs of the resulting ProVerif model do not necessarily imply proof of the source code. Instead, we use model translation as a pragmatic tool to automatically generate readable protocol models faithful to the implementation, and to find bugs in the implementation. We have experimented with multiple protocols written in ProScript, including OTR, SP, and TLS 1.3, and by carefully inspecting the source code and target models, we find that the compiler is quite reliable and that it generates models that are not so far from what one would want to write directly in ProVerif. In future work, we plan to prove the soundness of this translation to get stronger positive guarantees from the verification. To this end, we observe that our source language is a simply-typed functional programming language, and hence we should be able to closely follow the methodology of [20].

Generating Top-Level Processes. We are also able to automatically generate top-level ProVerif processes. Aiming to implement this in a way that allows us to easily integrate ProScript code into existing codebases, we decided to describe top-level functions inside module.exports, the export namespace used by modules for Node.js [21], a popular client/server run-time for JavaScript applications (based on the V8 engine). This makes intuitive sense: module.exports is used specifically in order to define the functions of a Node.js module that should be available to the external namespace once that module is loaded, and executing all this functionality 33 Deliverable D4.2 NEXTLEAP Grant No. 688722

150 PSCL SJCL 100 MSRCrypto 50

Milliseconds 0 0 500 1,000 1,500 2,000 2,500 3,000 3,500 4,000 4,500 Iterations

Figure 3: Each SHA256 iteration hashes 16 blocks. in parallel can give us a reasonable model of a potential attacker process. Therefore, functions declared in this namespace will be translated into top-level processes executed in parallel. We use ProVerif tables in order to manage persistent state between these parallel processes: each process fetches the current state from a table, runs a top-level function in that state, and stores the updated state returned by the function in the table.

4.4 Trusted Libraries for ProScript

Protocol implementations in ProScript rely on a few trusted libraries, in particular, for cryptographic primitives and for encoding and decoding protocol messages.

When deployed in Node.js or within a browser, the protocol code may have access to native cryptographic APIs. However, these APIs do not typically provide all modern cryptographic primitives; for example, the W3C Web Cryptography API does not support Curve25519, which is needed in Signal. Consequently, implementations like Signal Messenger end up compiling cryptographic primitives from C to JavaScript. Even if the desired primitives were available in the underlying platform, accessing them in a hostile environment is unsafe, since an attacker may have redefined them. Consequently, we developed our own libraries for cryptography and message encoding.

The ProScript Cryptography Library (PSCL) is a trusted cryptographic library implementing a variety of modern cryptographic primitives such as X25519, AES-CCM and BLAKE2. All of its primitives are fully type-checked without this affecting speed: in the majority of our benchmarks, PSCL is as fast as or faster than popular JavaScript cryptographic libraries like SJCL and MSR JavaScript Crypto, which do not even benefit from defen- sive type checking (Figure 3).

More crucially, PSCL functions used in ProScript code are detected by the ProScript compiler as it produces the applied pi model of the implementation, giving it the ability to convert each call to a cryptographic primitive to a call to the corresponding symbolic function in ProVerif. For example, if the ProScript compiler sees a call to PSCL’s X25519 implementation, it will automatically translate it to a standard Diffie-Hellman construction in ProVerif.

5 Implementing and Verifying SP

We describe SP, a variant of Signal Protocol that closely follows TextSecure version 3. We show how we implement and verify this protocol in our framework.

5.1 Protocol Overview

In SP, as illustrated in Figure 4, each client publishes a long-term Diffie-Hellman public key and a set of ephemeral Diffie-Hellman public keys (called “pre-keys”). These keys include both signed pre-keys, which can be reused for some period of time, and non-signed, one-time pre-keys, which are fresh at each session. To 34 Deliverable D4.2 NEXTLEAP Grant No. 688722

Alice Bob

a3dh asig b b Has identity (a3dh,asig),(g ,g ) Has identity (b3dh,bsig),(g 3dh ,g sig ) Knows identity (gb3dh ,gbsig ) Knows identity (ga3dh ,gasig ) b Has signed pre-key bs,g s b bs bo Has one-time pre-key , o SIGN(bsig,g ),g bo g

ae Zp ∈ S = c ga3dhbs gaeb3dh gaebs gaebo 0 | | | | (rk ,ck ) HKDF(S,c ,c ) ba ba ⇐ 1 2

ae0 Zp ∈ a bs kshared = g e0 (rk ,ck ) HKDF(k ,rk ,c ) ab ab ⇐ shared ba 2 k HKDF(HMAC(ck ,c ),c ,c ) enc ⇐ ab 3 1 4 ga3dh ,gasig ,gae ,gae ,E = ENC(k ,M ,ga3dh gasig gb3dh gbsig gae ) 0 0 enc 0 | | | | 0

S = c ga3dhbs gaeb3dh gaebs gaebo 0 | | | | (rkba,ckba) HKDF(S,c1,c2) ⇐ b Delete pre-key(bo,g o )

a bs kshared = g e0 (rk ,ck ) HKDF(k ,rk ,c ) ab ab ⇐ shared ba 2 k HKDF(HMAC(ck ,c ),c ,c ) enc ⇐ ab 3 1 4 M DEC(k ,E ,ga3dh gasig gb3dh gbsig gae ) 0 ⇐ enc 0 | | | | 0

be Zp ∈ a be kshared = g e0 (rk ,ck ) HKDF(k ,rk ,c ) ba ba ⇐ shared ab 2 k HKDF(HMAC(ck ,c ),c ,c ) enc ⇐ ba 3 1 4

gbe ,E = ENC(k ,M ,gb3dh gbsig ga3dh gasig gbe ) 1 enc 1 | | | |

a be kshared = g e0 (rk ,ck ) HKDF(k ,rk ,c ) ba ba ⇐ shared ab 2 k HKDF(HMAC(ck ,c ),c ,c ) enc ⇐ ba 3 1 4 M DEC(k ,E ,gb3dh gbsig ga3dh gasig gbe ) 1 ⇐ enc 1 | | | |

Figure 4: SP, a variant of Signal with minor differences. Alice requests a signed pre-key from Bob (via the server) and sends an initial message M0. Bob accomplishes his side of the key exchange and obtains M0. Bob later sends his reply M1, illustrating the Axolotl ratchet post-AKE. We ignore the hash-based ratchet that occurs when two consecutive messages are sent in the same direction. ci refers to various constants found throughout the protocol. send a message to Bob, Alice retrieves Bob’s long-term keys (gb3dh ,gbsig ), a signed pre-key gbs and a one-time pre-key gbo . She then chooses her own ephemeral gae . A four-way Diffie-Hellman handshake is accomplished using Alice and Bob’s long-term identity keys and their short-term ephemeral keys in order to derive the session secret S. The one-time pre-key is optional: when there remains no available one-time pre-key, the exchange is performed with a triple Diffie-Hellman handshake. An encryption key, kenc, is then derived from S by Hash-Based Key Derivation (HKDF) [22] and the message M0 is sent encrypted under the authenticated encryption scheme AES-GCM, with public and ephemeral keys as associated data: ENC(k,m,ad) means that m is encrypted with k and both the message m and the associated data ad are authenticated. Subsequent messages in the con- versation obtain authentication by chaining to S via a forward-ratcheting construction that also employs HKDF. Each sent message includes its own newly generated ephemeral public key and the protocol’s double ratchet key refresh mechanism manages the key state by advancing key chaining with every message.

SP’s forward and future secrecy goals are intended to make it so that the compromise of Alice or Bob’s long- term keys allows for their impersonation but not for the decryption of their messages. The use of a signed initial ephemeral pre-key results in weaker forward secrecy guarantees for the first flight of messages from A to B: 35 Deliverable D4.2 NEXTLEAP Grant No. 688722 no forward secrecy is provided if both the long-term keys and pre-keys are leaked, although the guarantees for subsequent flights remain strong. If pre-keys are not signed, then the protocol only offers weak forward secrecy with respect to long-term key leakage. We note that the term “forward secrecy” can be confusing in a protocol like Signal, because a number of keys are at stake: long-term keys ((a3dh,asig),(b3dh,bsig)), signed pre-key bs, one-time pre-key bo, ephemeral keys (ae,a ,b ), root keys (rkab,ckab,rkba,ckba) and message keys (kenc). e0 e0 Any formal analysis of the protocol must precisely state which of these keys can be compromised and when.

Differences from other versions of Signal

An earlier version of the protocol, TextSecure Version 2, was cryptographically analyzed in previous work [2]. There are two key differences between SP and TextSecure Version 2.

Signed, Time-Based Pre-Keys. Version 2 uses a triple Diffie-Hellman handshake with one of a hundred pre- keys that Bob stores on the server (including a “last-resort” pre-key). TextSecure Version 3 and all subsequent versions of Signal, including SP, use a signed time-based pre-key, used in conjunction with an unsigned one- time pre-key in case it is available. Bob periodically replaces his signed pre-key (for example, once every week), which may be re-used until its replacement and refreshes his collection of unsigned one-time pre-keys. In SP, when one-time pre-keys are exhausted, no “last-resort” pre-key is used.

Stronger Identity Protection. Since Version 3, tagn is expanded to include the long-term identities of the sender and recipient, which is not the case in Version 2. This provides a slightly stronger authentication guarantee in the rare case that the encryption keys for different pairs of users turns out to be the same.

In addition to these differences with Version 2, SP also differs from other variants of Signal in one key aspect. In SP, long-term identities are split into one Diffie-Hellman key pair and one signing key pair. In Signal, the same key pair is used for both operations, by applying an elliptic curve conversion from the Montgomery curve-based Diffie-Hellman key pair to obtain its twisted Edwards curve-based signing key pair equivalent. We choose to use separate keys instead, because in our cryptographic proof, we do not want to add a non-standard cryptographic assumption about the use of the same key in two independent cryptographic operations. In exchange for using standard cryptographic assumptions, we consider the cost of adding an extra 32 byte key to the protocol to be acceptable.

5.2 Protocol Implementation

To implement SP in ProScript, we must first deconstruct it into various protocol components: structures for managing keys and user states, messaging functions, APIs and top-level processes. ProScript is well-equipped to handle these protocol components in a way that lends itself to model extraction and verification. We break down our ProScript SP implementation into:

Types for State and Key Management. ProScript’s type declaration syntax can be used to declare types for individual elements such as encryption keys but also for collections of elements such as a conversation party’s state. These declarations allow for the construction of common data structures used in the protocol and also makes their management and modification easier in the extracted ProVerif models.

Messaging Interface. The ProScript implementation exposes the generic messaging API in a single global object. All interface access provides purely state-passing functionality.

a ab Long-Term and Session States. Protocol functions take long-term and session states (S ,Tn ) as input and ab a return Tn+1. S contains long-term values such identity keys, while T includes more session-dependent values such as ephemerals, containing the current ephemeral and chaining keys for the session context and status, indicating whether the application layer should perform a state update.

36 Deliverable D4.2 NEXTLEAP Grant No. 688722

Goals Messages Parties Roles Time Secrecy 1 A, B One 00h.04m.07s. Secrecy 1 A, B Two 00h.11m.17s. Indist. 1 A, B One 02h.06m.15s. Authen. 1 A, B, M One 00h.58m.19s. Authen. 1 A, B, M Two 29h.17m.39s. Fo. Se. 1 A, B One 00h.04m.14s. KCI 1 A, B One 00h.19m.20s.

Figure 5: Verification times for SP ProVerif models.

Internal Functions. Utility functionality, such as key derivation, can also be described as a series of pure functions that are not included in the globally accessible interface.

Top-Level Process. A top-level process can serve as a harness for testing the proper functioning of the protocol in the application layer. Afterwards, when this top-level process is described in the extracted ProVerif model, the implementer will be able to use it to define which events and security properties to query for.

Inferred Types in ProScript. ProScript type declarations allow for the easier maintenance of a type-checkable protocol implementation, while also allowing the ProScript compiler to translate declared types into the extracted ProVerif model. Defining a key as an array of 32 bytes will allow the ProScript compiler to detect all 32 byte arrays in the implementation as keys and type their usage accordingly.

5.3 Protocol Verification

We use ProVerif to verify the security goals of our extracted model by defining defining queries that accurately test the resilience of security properties against an active adversary. Under an active Dolev-Yao adversary, ProVerif was able to verify confidentiality, authenticity, forward secrecy and future secrecy for Alice and Bob initializing a session and exchanging two secret messages, with a compromised participant, Mallory, also being allowed to initialize sessions and exchange non-secret messages with Alice and Bob. Our analysis revealed two novel attacks: a key compromise impersonation attack and a replay attack, for which we propose a fix. Aside from these attacks, we were also able to model the previously documented Unknown Keyshare Attack [2].

Extracts of our compiled SP implementation are available online [23]. Models begin with type declarations followed by public constant declarations, equational relationships for cryptographic primitives, protocol functions, queries and relevant names and finally the top-level process with its associated queries.

The top-level process queries for security properties such as confidentiality, authenticity and forward secrecy between two roles: an initiator (e.g. Alice) who sends an initial message and thereby initializes an authenticated key exchange, and a responder (e.g. Bob) who receives the message and who may send a response. Some models include a third compromised identity, Mallory, who also communicates with Alice and Bob but while leak- ing her private keys to the attacker beforehand. In some instances, we also model parallel process executions where each identity (Alice, Bob and optionally Mallory) assumes both the role of the initiator and the responder. We informally call this latter scenario a “two-way role” model.

Secrecy and Indistinguishability. For every message considered in our protocol model, we define a secret constant Mn where M1 is the initial message in a session. These secret values are then used as the plaintext for the encrypted messages sent by the principals. We show that an active attacker cannot retrieve a message’s plaintext Mn using the query: query(attacker(Mn)) (1)

Similarly, we show indistinguishability using the query query(noninterf(Mn)). 37 Deliverable D4.2 NEXTLEAP Grant No. 688722

Forward and Future Secrecy. We examine forward and future secrecy in Signal Protocol in multiple scenarios: the compromise of long-term keys and the compromise of message keys in two different types of message flights. In these scenarios, we need to model that keys are leaked after sending or receiving certain messages. We rely on ProVerif phases for that: intuitively, t represents a global clock, and processes occurring after the declaration of a phase t are active only during this phase.

We show that message M1 remains secret by query (1) even if the long-term keys (a3dh,asig,b3dh,bsig) are leaked after sending M1. Furthermore, we can modify our ProVerif model to produce a sanity check: if responder Bob skips the signature check on gas , ProVerif shows that an active attacker becomes capable of violating this forward secrecy property.

Next, we examine two different messaging patterns in the Double Ratchet algorithm and find that they approach forward and future secrecy differently:

Single-Flight Pattern. In this scenario, Alice sends Bob a number of messages M and M where n > 1 • n n+1 and does not receive a response. In this scenario, Bob’s lack of response does not allow Alice to obtain a be ab fresh ephemeral key share g required to establish a new kshared in Tn+1 to be used for Mn+1, so Alice just ab n+1 updates the key ckab by hashing it. If Alice’s session state Tn+1, (which, recall, contains ae and (rkab,ckab) for Mn+1), is leaked, then Mn remains secret (forward secrecy). Obviously, to take advantage of this property in case of compromise, the keys (rkab,ckab) for Mn must have been appropriately deleted, which is delicate

when messages are received out-of-order: if Mn1 ,...,Mnk (n1 < ... < nk) have been received, the receiver

should keep the chaining key ckab for Mnk+1 and the encryption keys kenc for the messages Mi not received ab yet with i < nk. If Tn is leaked, then Mn+1 is not secret, so no future secrecy is obtained. Message-Response Pattern. In this scenario, Alice sends Bob a single message M where n > 1 and • n receives a response Mn+1 before sending Mn+2. Upon receiving Mn+1, Alice will be able to derive a fresh n+2 n+1 ae be ab ab kshared = g . As a result, if Tn+2 is leaked, then Mn remains secret (forward secrecy) and if Tn is leaked after Mn+1 is received, then Mn+2 remains secret (future secrecy).

Message Authenticity. Signal Protocol relies on a Trust-on-First-Use (TOFU) authentication model: Alice as- sumes that Bob’s advertised identity key is authenticated and untampered with and employs it as such until an event causes the trust of the key to be put in question, such as a sudden identity key change or an out of band verification failure. We model TOFU by embedding Alice and Bob’s identity keys into each other’s initial states. We are then free to model for message authenticity: informally, if B receives a message M from A, we want A to have sent M to B. In ProVerif, we can specify two events: Send(A,B,M), which means that A sends M to B and Recv(A,B,M), which means that B receives M from A. We can then formalize the correspondence

event(Recv(A,B,M)) = event(Send(A,B,M)) (2) ⇒ which checks if for all Recv(A,B,M) events, it must be the case that a Send(A,B,M) event has also been executed.

ProVerif succeeds in proving correspondence (2) using public keys A and B. While this implies the desired property when the relation between the public keys and the identity of the principals is bijective, a limitation of this approach is that the identities of the principals are only expressed in terms of keys and not as a more personally-linked element, such as for example a phone number. Therefore, we cannot formally express stronger identity binding as part of the protocol model. This point leads to the Unknown Key Share Attack first reported for Signal Protocol Version 2 [2]: if an adversary can register the public keys (gb3dh ,gbsig ) of B as public keys of C and A sends a message to C, then C can forward this message to B and B will accept it as coming from A, since B and C have the same public keys.

No Replays. This property is similar to message authenticity, but uses an injective correspondence instead, which means that each execution of Recv(A,B,M) corresponds to a distinct execution of Send(A,B,M):

inj-event(Recv(A,B,M)) = inj-event(Send(A,B,M)) ⇒

38 Deliverable D4.2 NEXTLEAP Grant No. 688722

When a optional one-time pre-key is involved in the initial session handshake, ProVerif shows that the injective correspondence holds for the first message in the conversation. However, when this optional one-time pre-key is not used, a replay attack is detected. Signal Protocol Version 3 will accept a Diffie-Hellman handshake that only employs identity keys and signed pre-keys, both of which are allowed to be reused across sessions. This reuse is what makes a replay attack possible. We propose a fix for this issue by having clients keep a cache of the ephemeral keys used by the sender of received messages, associated with that sender’s identity key. We are able to expand our event queries in ProVerif to account for this fix by showing the non-injective correspondence of the Send and Recv events with added ephemeral keys. Coupled with a caching of ephemeral keys, we can ensure that the Recv event is only executed once per ephemeral key. Hence, the injective correspondence is implied by the non-injective correspondence.

Key Compromise Impersonation (KCI). We present a novel key compromise impersonation attack: to detect KCI, we consider a scenario in which Alice or Bob’s keys are compromised and test again for authenticity of messages received by the compromised principal. When Alice or Bob’s long-term secret key is compromised, ProVerif shows that message authenticity still holds. However, when Bob’s signed pre-key is also compromised, ProVerif finds an attack against message authenticity. This is a novel key compromise impersonation attack: when the adversary has Bob’s signed pre-key s, he can choose x and x0 and compute the session keys using Alice’s and Bob’ public keys (ga3dh ,gasig ) and (gb3dh ,gbsig ) and Bob’s one time pre-key go and send his own message in Alice’s name. This message is accepted by Bob as if it came from Alice: the event Recv(A,B,M) is executed without having executed Send(A,B,M).

5.4 Other Protocols: OTR

To obtain higher confidence in ProScript’s usability as an implementation and verification framework, we also im- plemented Off-the-Record (OTR) Messaging Version 2, which has been shown to include various vulnerabilities discovered under finite-state analysis by Bonneau and Morrison [24]. OTR [17] uses a SIGMA-based key ex- change [25] and a ratcheting scheme in order to achieve confidentiality, authentication, perfect forward secrecy and deniability. During model verification, known vulnerabilities in OTR Version 2 were automatically detected:

Version Rollback Attack. Since the communication of which OTR versions are supported by a client was performed before authentication occurred, it is possible to maliciously force users to adopt an outdated version of OTR.

Unknown Key-Share Attack. Since OTR’s authenticated key exchange lacks sufficient information identifying Alice’s intended recipient, Mallory can forward handshake messages in order to successfully trick Alice into establishing a session with Bob, whereas Alice intended to establish a session with Mallory.

Message Integrity Attack. If Alice receives a message from Bob where Bob uses new ratchet keys, she will publish her MAC keys for her previous message. This is an intentional feature meant to provide deniability once both parties are certain that a certain step of ratchet keys are obsolete. However, Mallory can simply block this outgoing message, use it to learn the MAC key for Alice’s previous message and commit a forgery under those keys. From Bob’s perspective, it would appear that he has received a delayed but nevertheless valid message from Alice.

Integrating Symbolic Verification into the Development Cycle. Human-readability of the automatically com- piled ProVerif model is key to our verification methodology. In the case of a query failure, users can opt to modify their implementation and recompile into a new model, or they can immediately modify the model itself and re-test for security queries within reasonable model verification times. For example, if an implementer wants to test the robustness of a passing forward secrecy query, they can disable the signature verification of signed pre-keys by changing a single line in the model, causing the client to accept any pre-key signature.

39 Deliverable D4.2 NEXTLEAP Grant No. 688722

5.5 Results of Key Compromise

((a ,a ),(b ,b )) Alice and Bob lose authenticity guarantees for all subsequent messages. Keys in • 3dh sig 3dh sig secrets are vulnerable to a device-level attacker due to their permanent storage and reuse across all ses- sions. (a ,gae ,b ,gbo ) In Signal Protocol Version 2, and only in the case of an earlier long-term key compromise (a • e o or b), Alice and Bob lose confidentiality and integrity guarantees for the subsequent message. ck T ab Immediate loss of confidentiality and integrity for the subsequent message. • ab ∈ n

6 Cryptographic Proofs with CryptoVerif

To complement the results obtained in the symbolic model using ProVerif, we use the tool CryptoVerif [5] in order to obtain security proofs in the computational model. This model is much more realistic: messages are bitstrings; cryptographic primitives are functions from bitstrings to bitstrings; the adversary is a probabilistic Turing machine. CryptoVerif generates proofs by sequences of games [26, 27], like those written manually by cryptographers, automatically or with guidance of the user.

The computational model is more realistic, but it also makes it more difficult to mechanize proofs. For this reason, CryptoVerif is less flexible and more difficult to use than ProVerif, and our results in the computational model are more limited. We model only one message of the protocol (in addition to the pre-keys), so we do not prove properties of the ratcheting algorithm. Considering several data messages exceeds the current capabilities of CryptoVerif—the games become too big.

Rather than directly using models generated from our ProScript code, we manually rewrite the input scripts of CryptoVerif, for two main reasons:

The syntax of the protocol language of CryptoVerif differs slightly from that of ProVerif. We plan to overcome • this difficulty in the future by modifying the syntax of CryptoVerif so that it is compatible with ProVerif.

The kinds of models that are easy to verify using CryptoVerif differ from those that are easy for ProVerif; • therefore, even if the source syntax were the same, we would still need to adapt our compiler to generate specialized models that would be more conducive to CryptoVerif’s game-based proofs.

6.1 Assumptions

We make the following assumptions on the cryptographic primitives:

The elliptic curve Ec25519 satisfies the gap Diffie-Hellman (GDH) assumption [28]. This assumption means • that given g, ga, and gb for random a,b, the adversary has a negligible probability to compute gab (computa- tional Diffie-Hellman assumption), even when the adversary has access to a decisional Diffie-Hellman oracle, which tells him given G,X,Y,Z whether there exist x,y such that X = Gx, Y = Gy, and Z = Gxy. When we consider sessions between a participant and himself, we need the square gap Diffie-Hellman variant, which 2 additionally says that given g and ga for random a, the adversary has a negligible probability to compute ga . This assumption is equivalent to the GDH assumption when the group has prime order [29], which is true for y y y y Ec25519 [30]. We also added that x = x0 implies x = x0 and that x = x 0 implies y = y0, which hold when the considered Diffie-Hellman group is of prime order.

Ed25519 signatures, used for signing pre-keys, are unforgeable under chosen-message attacks (UF-CMA) [31]. •

40 Deliverable D4.2 NEXTLEAP Grant No. 688722

The functions • x ,x ,x ,x HKDF(x x x x ,c ,c ) 1 2 3 4 7→ 1k 2k 3k 4 1 2 x ,x ,x HKDF(x x x ,c ,c ) 1 2 3 7→ 1k 2k 3 1 2 x,y HKDF(x,y,c ) 7→ 2 x HKDF(x,c ,c ) 7→ 1 4

are independent random oracles, where x, y, x1, x2, x3, x4, and c1 are 256-bit long. We further justify this assumption in the Appendix: there, we show that these functions are indifferentiable [32] from independent random oracles, assuming that the compression function underlying SHA256 is a random oracle. (The con- sidered HKDF function [22] is defined from HMAC-SHA256, which is itself defined from SHA256.)

HMAC-SHA256 is a pseudo-random function (PRF) [33]. This assumption is used for HMAC(ck , ) and • ab · HMAC(ck , ). ba · The encryption scheme ENC, which is AES-GCM, is a secure authenticated encryption with associated data • (AEAD). More precisely, it is indistinguishable under chosen plaintext attacks (IND-CPA) and satisfies cipher- text integrity (INT-CTXT) [34, 35].

CryptoVerif provides a library that predefines the most common cryptographic assumptions, so that the user does not have to write them for each protocol. In our work, we had to adapt these predefined assumptions to our specific needs: the GDH assumption is predefined, but the square GDH variant is not; unary random oracles are predefined, but we also needed binary, ternary, and 4-ary ones; predefined PRFs, SUF-CMA MACs, and IND-CPA encryption schemes use a key generation function, while in our schemes the key is a plain random bitstring, without a key generation function. Adapting the definition of primitives did not present any major difficulty. As mentioned in 5.1, we had to make one modification to the original Signal Protocol, for it to be § provable in the computational model: we use different keys for the elliptic curve Diffie-Hellman and elliptic curve signatures. It is well-known that using the same keys for several cryptographic primitives is undesirable, as proving security requires a joint security assumption on the two primitives in this case. Therefore, we assume each protocol participant to have two key pairs, one for Diffie-Hellman and one for signatures. This problem remains undetected in a symbolic analysis of the protocol.

6.2 Protocol Model

We model SP as a process in the input language of CryptoVerif, which is similar to the one of ProVerif. We consider simultaneously the protocol of Figure 4 and the version without the optional one-time pre-key bo. As mentioned above, we consider only one message in each session. Our threat model includes an untrusted network, malicious principals, and long-term key compromise, as mentioned in 2. It does not include session § state compromise, which is less useful with a single message.

At a high level, we use the same messaging API as in 2. However, to make verification easier for CryptoVerif, we § specify a lower-level interface. We consider two honest principals Alice and Bob, and define separate processes for Alice interacting with Bob, with herself, or with a malicious participant, Bob interacting with Alice, and Bob interacting with himself or a malicious participant, as well as similar processes with the roles of Alice and Bob reversed. The adversary can then implement the high-level interface of 2 from this lower-level interface: the § adversary is supposed to implement the malicious principals (including defining keys for them) and to call the low-level interface processes to run sessions that involve the honest principals Alice and Bob.

We make two separate proofs: In the first one, we prove the security properties for sessions in which Bob generates pre-keys and runs the protocol with Alice. (Other protocol sessions exist in parallel as described above; we do not prove security properties for them. For sessions for which we do not prove security properties, we give to the adversary the ephemeral ae0 and the key rkba or rkba and let the adversary encrypt and MAC the message himself, to reduce the size of our processes.) In the second one, we prove the security properties for sessions in which Alice generates pre-keys and runs the protocol with herself. Bob is included in the adversary 41 Deliverable D4.2 NEXTLEAP Grant No. 688722 in this proof. The security for sessions in which Alice generates pre-keys and runs the protocol with Bob follows from the first proof by symmetry. The security for sessions in which Bob generates pre-keys and runs the protocol with himself follows from the second proof. The other sessions do not satisfy security properties since they involve the adversary. (They must still be modeled, as they could break the protocol if it were badly designed.) Therefore, these two proofs provide all desired security properties.

6.3 Security Goals

We consider the following security goals from 2: § Message Authenticity, No Replays, and Key Compromise Impersonation (KCI). These properties are mod- eled by correspondences as in ProVerif ( 5.3). For key compromise impersonation, we consider the compromise § of the long-term Diffie-Hellman and signature keys of Bob, and prove again message authenticity. We do not consider the compromise of the signed pre-key since we already know from the symbolic analysis that there is an attack in this case.

Computational Indistinguishability. If A randomly chooses between two messages M0, M1 of the same length and sends one of them to B, then the adversary has a negligible probability of guessing which of the two messages was sent. In our model, this is formalized by choosing a random bit secb 0,1 ; then A sends ∈ { } message Mb to B, and we show that the bit secb remains secret, with the query secret secb.

Forward Secrecy. This is proved exactly like indistinguishability, but with an additional oracle that allows the adversary to obtain the secret keys of the principals, thus compromising them.

We do not consider future secrecy since we have a single message. We do not consider secrecy since we directly deal with the stronger property of indistinguishability.

6.4 Results

CryptoVerif proves message authenticity, absence of key compromise impersonation attacks (when the long- term keys of Bob are compromised), indistinguishability, and forward secrecy, but cannot prove absence of replays. This is due to the replay attack mentioned in 5.3. Since this attack appears only when the optional § one-time pre-key is omitted, we separate our property into two: we use events Send(A,B,M) and Recv(A,B,M) for the protocol with optional pre-key and events Send3(A,B,M) and Recv3(A,B,M) for the protocol without optional pre-key. CryptoVerif then proves

inj-event(Recv(A,B,M)) = inj-event(Send(A,B,M)) ⇒ event(Recv3(A,B,M)) = event(Send3(A,B,M)) ⇒ which proves message authenticity and no replays when the one-time pre-key is present and only message authenticity when it is absent. This is the strongest we can hope for the protocol without anti-replay countermea- sure.

With our anti-replay countermeasure ( 5.3), CryptoVerif can prove the absence of replays, thanks to a recent § extension that allows CryptoVerif to take into account the replay cache in the proof of injective correspondences, implemented in CryptoVerif version 1.24. Our CryptoVerif proofs have been obtained with some manual guid- ance: we indicated the main security assumptions to apply, instructed CryptoVerif to simplify the games or to replace some variables with their values, to make terms such as ma = mb appear. The proofs were similar for all properties.

42 Deliverable D4.2 NEXTLEAP Grant No. 688722

Goals Parties Running Time Forward Secrecy A, B, M 3 min. 58 sec. Forward Secrecy A, M 7 min. 04 sec. KCI A, B, M 3 min. 15 sec. Others A, B, M 4 min. 15 sec. Others A, M 3 min. 35 sec.

Figure 6: Verification times for SP CryptoVerif models, without anti-replay countermeasure. The runtimes with the anti-replay countermeasure are of the same order of magnitude. Tested using CryptoVerif 1.24.

Internet

Untrusted Chat Window Process Threads M M (JavaScript) B A 1 Trusted 8 MA 2 Messaging Untrusted Protocol Process RenderMsg(P ) A 4 PA = Decrypt(MA) Main 3 Thread Network (ProScript) P PB Process 6 B 5 Thread Verified Keys & (JavaScript) MB = Encrypt(PB) Protocol State 7

Figure 7: Cryptocat Architecture: isolating verified and untrusted components in Electron apps within separate processes.

7 A Verified Protocol Core for Cryptocat

We now describe how we can rewrite Cryptocat to incorporate our ProScript implementation of SP. We decon- struct the Cryptocat JavaScript code into the following components, as advocated in Figure 2.

1. Unverified JavaScript Application This component, which comprises the majority of the code, manages the user’s state, settings, notifications, graphical interface and so on. It is connected to the protocol only via the ability to call exposed protocol functions (as documented in 2.1). We adopt certain assumptions regarding § the unverified JavaScript application, for example that it will not modify the protocol state outside of passing it through the protocol implementation interface.

2. Verified Protocol Implementation This component is written in ProScript and resides in a separate names- pace, functioning in a purely state-passing fashion. Namely, it does not store any internal state or make direct network calls. This implementation is type-checked, and automatically verified every time it is modified.

3. Trusted Library This component provides cryptographic functionality. A goal is to include modern crypto- graphic primitives (X25519, AES-CCM) and provide type-checking assurances without affecting speed or performance.

This layered architecture is essential for our verification methodology, but is quite different from other messag- ing applications. For example, the Signal Desktop application is a Chrome browser application also written in JavaScript [36]. Parts of the protocol library are compiled from C using , presumably for performance, parts are taken from third-party libraries, and other protocol-specific code is written in JavaScript. The resulting code (1.5MB, 39Kloc) is quite hard to separate into components, let alone verify for security. We hope that our layered approach can lead to verified security guarantees without sacrificing performance or maintainability.

43 Deliverable D4.2 NEXTLEAP Grant No. 688722

7.1 Isolating Verified Code

We build Cryptocat using Electron [37], a framework for JavaScript desktop applications. Electron is built on top of the Node.js JavaScript runtime and the Chromium web renderer. Electron has recently gained strong adoption: popular applications such as , , Slack, WordPress and WhatsApp Desktop are all built on top of Electron.

By default, Electron allows applications to load any Node.js low-level module, which can in turn perform danger- ous operations like accessing the file system and exfiltrate data over the network. Since all Node.js modules in a single process run within the same JavaScript environment, malicious or buggy modules can tamper with other modules via prototype poisoning or other known JavaScript attack vectors. Consequently, all Electron apps, including other desktop Signal implementations like WhatsApp and Signal messenger effectively include all of Electron and Node.js into their trusted computing base (TCB).

We propose a two-pronged approach to reduce this TCB.

Language-Based Isolation. Since ProScript is a subset of Defensive JavaScript, ProScript protocol code is isolated at the language level from other JavaScript code running within the same process, even if this code uses dangerous JavaScript features such as prototype access and modification. To ensure this isolation, ProScript code must not call any external (untyped) libraries.

Process Thread Isolation. We exploit features of Electron in order to isolate components of our application in different CPU threads as seen in Figure 7. When a message arrives on the network (1), the main network thread can only communicate with our Protocol TCB using a restrictive inter-process communication API. The TCB then uses its internal verified protocol functionality and state management to return a decryption of the message (3), which is then forwarded again via IPC to the chat window (4), a third separate CPU thread which handles message rendering. Furthermore, the TCB process is disallowed from loading any Node.js modules.

In particular, the network process is isolated from the chat media rendering process; neither ever obtain access to the key state or protocol functionality, which are all isolated in the ProScript protocol process. When Bob responds, a similar IPC chain of calls occurs in order to send his reply back to Alice (5, 6, 7, 8). Even if an error in the rendering code or in the XML parser escalated into a remote takeover of the entire web renderer, the calls to the protocol TCB would be restricted to those exposed by the IPC API. However, these isolation techniques only protect the ProScript code within our application when executed within a correct runtime framework. None of these techniques can guard against bugs in V8, Node.js, or Electron, or against malicious or buggy Node.js or Electron modules loaded by the application.

7.2 Performance and Limitations

Although we have verified the core protocol code in Cryptocat and tried to isolate this code from unverified code, the following limitations still apply: we have not formally verified the soundness of the cryptographic primitives themselves, although writing them in Defensive JavaScript does provide type safety. We have also not formally verified the Electron framework’s isolation code. Similarly, we do not claim any formal verification results on the V8 JavaScript runtime or on the Node.js runtime. Therefore, we rely on a number of basic assumptions regarding the soundness of these underlying components. Cryptocat’s successful deployment provides a general guideline for building, formally verifying, and isolating cryptographic protocol logic from the rest of the desktop runtime. Designing better methods for implementing and isolating security-critical components within Electron apps with a minimal TCB remains an open problem. Despite the strong programming constraints imposed by our verification architecture, we find that Cryptocat is able to perform similarly to mainstream desktop messaging applications that do not offer end-to-end encryption, such as Skype. In order to benefit from automatic model translation of our ProScript protocol implementation (as described in 4.4), we use PSCL as our cryptography library, § which allows us to easily handle even large file encryptions (200+MB) for Cryptocat’s file sharing feature. Our application is available for Windows, Linux and Mac, and currently serves over 20,000 users weekly. It is capable

44 Deliverable D4.2 NEXTLEAP Grant No. 688722 of handling multi-device provisioning for users with soft device revocation and device authentication. We also support video messaging, file sharing and similar usability features, which all exploit the isolation and formal verification methods described in this paper.

8 Related Work

Extracting Protocol Models from Running Code. There have been previous attempts [38] to extract ProVerif models from typed JavaScript, such as DJS2PV [7]. However, DJS2PV was only tested on small code examples: attempting to translate a complete implementation such as Signal Protocol resulted in a 3,800 line model that attempts to precisely account for the heap, but could not verify due to an exploding state space. Previous efforts such as FS2PV [20] avoided this problem by choosing a purely functional source language that translated to simpler pi calculus scripts. We adopt their approach in ProScript to generate briefer, more readable models.

Type Systems for JavaScript. TypeScript [39], Flow [40], Defensive JavaScript and TS* [41] all define type systems that can improve the security of JavaScript programs. The type system in ProScript primarily serves to isolate protocol code from untrusted application and to identify a subset of JavaScript that can be translated to verifiable models.

Formal Analysis of Web Security Protocols. Tools like WebSpi [42] and AuthScan [43] have been used to verify the security of web security protocols such as OAuth. An expressive web security model has also been used to build manual proofs for cryptographic web protocols such as BrowserID [44]. These works are orthogonal to ProScript and their ideas can potentially be used to improve our target ProVerif models.

Analysis of Secure Messaging Protocols. Unger et al. survey previous work on secure messaging [10]. We discuss three recent closely-related works here.

Future secrecy was formalized by Cohn-Gordon et al. as “post-compromise security” [45]. Our symbolic formu- lation is slightly different since it relies on the definition of protocol phases in ProVerif.

Cryptographic security theorems and potential unknown key-share attacks on TextSecure Version 2 were pre- sented by Frosch et al. [2]. In comparison to that work, our analysis covers a variant of TextSecure Version 3, our analysis is fully mechanized, and we address implementation details. Our CryptoVerif model only covers a single message, but we consider the whole protocol at once, while they prove pieces of the protocol separately. Like we do, they consider that HKDF is a random oracle. We further justify this assumption by an indifferentiability proof.

More recently and in parallel with this work, Cohn-Gordon et al. [46] prove, by hand, that the message encryption keys of Signal are secret in the computational model, in a rich compromise scenario, under assumptions similar to ours. Thereby, they provide a detailed proof of the properties of the double ratcheting mechanism. However, they do not model the signatures of the signed pre-keys, and they do not consider key compromise impersonation attacks or replay attacks or other implementation-level details. In contrast to their work, our computational proof is mechanized, but limited to only one message.

9 Conclusion and Future Work

Drawing from existing design trends in modern cryptographic web application, we have presented a framework that supports the incremental development of custom cryptographic protocols hand-in-hand with formal security analysis. By leveraging state-of-the-art protocol verification tools and building new tools, we showed how many routine tasks can be automated, allowing the protocol designer to focus on the important task of analyzing her protocol for sophisticated security goals against powerful adversaries.

45 Deliverable D4.2 NEXTLEAP Grant No. 688722

We plan to continue to develop and refine ProScript by evaluating how it is used by protocol designers, in the spirit of an open source project. All the code and models presented in this paper, and a full version of this paper are available online [23]. Proving the soundness of translation from ProScript to ProVerif, by relating the source JavaScript semantics to the applied pi calculus, remains future work. The process of transforming the compiled model to a verified CryptoVerif script remains a manual task, but we hope to automate this step further, based on new and upcoming developments in CryptoVerif.

Finally, a word of caution: a protocol written in ProScript and verified with ProVerif or CryptoVerif does not immediately benefit from assurance against all possible attacks. Programming in ProScript imposes a strict discipline by requiring defensive self-contained code that is statically typed and can be translated to a verifiable model and subsequent verification can be used to eliminate certain well-defined classes of attacks. We believe these checks can add confidence to the correctness of a web application, but they do not imply the absence of security bugs, since we still have a large trusted computing base. Consequently, improving the robustness and security guarantees of runtime frameworks such as Electron, Node.js, and Chromium, remains an important area of future research.

Acknowledgments. This work was funded by the following grants: ERC CIRCUS, EU NEXTLEAP, and ANR AJACS.

References

[1] K. Bhargavan, A. Lavaud, C. Fournet, A. Pironti, and P. Strub, “Triple handshakes and cookie cutters: Breaking and fixing authenti- cation over TLS,” in IEEE Symposium on Security & Privacy (Oakland), 2014, pp. 98–113. [2] T. Frosch, C. Mainka, C. Bader, F. Bergsma, J. Schwenk, and T. Holz, “How secure is TextSecure?” in IEEE European Symposium on Security and Privacy (Euro S&P), 2016. [3] B. Blanchet, “Modeling and verifying security protocols with the applied pi calculus and ProVerif,” Foundations and Trends in Privacy and Security, vol. 1, no. 1–2, pp. 1–135, Oct. 2016. [4] D. Dolev and A. C. Yao, “On the security of public key protocols,” IEEE Transactions on Information Theory, vol. 29, no. 2, pp. 198–207, 1983. [5] B. Blanchet, “A computationally sound mechanized prover for security protocols,” IEEE Transactions on Dependable and Secure Computing, vol. 5, no. 4, pp. 193–207, 2008. [6] K. Bhargavan, A. Delignat-Lavaud, and S. Maffeis, “Language-based defenses against untrusted browser origins,” in USENIX Security Symposium, 2013, pp. 653–670. [7] K. Bhargavan, A. Delignat-Lavaud, and S. Maffeis, “Defensive JavaScript - building and verifying secure web components,” in Foundations of Security Analysis and Design (FOSAD VII), 2013, pp. 88–123. [8] M. Abadi and C. Fournet, “Mobile values, new names, and secure communication,” in 28th Annual ACM SIGPLAN-SIGACT Sym- posium on Principles of Programming Languages (POPL’01). London, United Kingdom: ACM Press, Jan. 2001, pp. 104–115. [9] H. Krawczyk, “HMQV: A High-performance Secure Diffie-Hellman Protocol,” in International Conference on Advances in Cryptology (CRYPTO), ser. Lecture Notes in Computer Science, V. Shoup, Ed., vol. 3621. Springer, 2005, pp. 546–566. [10] N. Unger, S. Dechand, J. Bonneau, S. Fahl, H. Perl, I. Goldberg, and M. Smith, “SoK: Secure Messaging,” in IEEE Symposium on Security & Privacy (Oakland), 2015. [11] N. Durov, “Telegram MTProto protocol,” 2015, https://core.telegram.org/mtproto. [12] O. Schirokauer, “The number field sieve for integers of low weight,” Mathematics of Computation, vol. 79, no. 269, pp. 583–602, 2010. [13] D. Gillmor, “Negotiated Finite Field Diffie-Hellman Ephemeral Parameters for Transport Layer Security (TLS),” 2016, IETF RFC 7919. [14] K. Bhargavan, A. Delignat-Lavaud, and A. Pironti, “Verified contributive channel bindings for compound authentication,” in Proceedings of the ISOC Network and Distributed System Security Symposium (NDSS ’15), Feb 2015. [Online]. Available: http://antoine.delignat-lavaud.fr/doc/ndss15.pdf [15] A. Rad and J. Rizzo, “A 2ˆ64 attack on Telegram, and why a super villain doesn’t need it to read your telegram chats.” 2015. [16] J. Jakobsen and C. Orlandi, “On the cca (in)security of mtproto,” Cryptology ePrint Archive, Report 2015/1177, 2015, http://eprint. iacr.org/2015/1177. [17] N. Borisov, I. Goldberg, and E. A. Brewer, “Off-the-record communication, or, why not to use PGP,” in Proceedings of the 2004 ACM Workshop on Privacy in the Electronic Society, WPES 2004, Washington, DC, USA, October 28, 2004, V. Atluri, P. F. Syverson, and S. D. C. di Vimercati, Eds. ACM, 2004, pp. 77–84. [Online]. Available: http://doi.acm.org/10.1145/1029179.1029200 46 Deliverable D4.2 NEXTLEAP Grant No. 688722

[18] N. Wilcox, Z. Wilcox-O’Hearn, D. Hopwood, and D. Bacon, “Report of Security Audit of Cryptocat,” 2014, https://leastauthority.com/ blog/least authority performs security audit for cryptocat.. [19] P. A. Gardner, S. Maffeis, and G. D. Smith, “Towards a program logic for JavaScript,” SIGPLAN Not., vol. 47, no. 1, pp. 31–44, Jan. 2012. [Online]. Available: http://doi.acm.org/10.1145/2103621.2103663 [20] K. Bhargavan, C. Fournet, A. D. Gordon, and S. Tse, “Verified interoperable implementations of security protocols,” ACM Transac- tions on Programming Languages and Systems, vol. 31, no. 1, 2008. [21] Joyent Inc. and the Linux Foundation, “Node.js,” 2016, https://nodejs.org/en/. [22] H. Krawczyk, “Cryptographic extraction and key derivation: The HKDF scheme,” in Advances in Cryptology (CRYPTO), ser. Lecture Notes in Computer Science. Springer, 2010, vol. 6223, pp. 631–648. [23] N. Kobeissi, “SP code repository,” https://github.com/inria-prosecco/proscript-messaging, February 2017. [24] J. Bonneau and A. Morrison, “Finite State Security Analysis of OTR Version 2,” 2006. [25] H. Krawczyk, “SIGMA: The ’SIGn-and-MAc’ approach to authenticated Diffie-Hellman and its use in the IKE-protocols,” in Advances in Cryptology - CRYPTO 2003, 23rd Annual International Cryptology Conference, Santa Barbara, California, USA, August 17-21, 2003, Proceedings, ser. Lecture Notes in Computer Science, vol. 2729. Springer, 2003, pp. 400–425. [26] V. Shoup, “Sequences of games: a tool for taming complexity in security proofs,” IACR Cryptology ePrint Archive, 2004, http: //eprint.iacr.org/2004/332. [27] M. Bellare and P. Rogaway, “The security of triple encryption and a framework for code-based game-playing proofs,” in Advances in Cryptology (Eurocrypt), ser. Lecture Notes in Computer Science, S. Vaudenay, Ed., vol. 4004. Springer, May 2006, pp. 409–426. [28] T. Okamoto and D. Pointcheval, “The gap-problems: a new class of problems for the security of cryptographic schemes,” in Practice and Theory in Public Key Cryptography (PKC), ser. Lecture Notes in Computer Science, K. Kim, Ed., vol. 1992. Springer, 2001, pp. 104–118. [29] A. Fujioka and K. Suzuki, “Designing efficient authenticated key exchange resilient to leakage of ephemeral secret keys,” in Topics in Cryptology (CT-RSA), ser. Lecture Notes in Computer Science, A. Kiayias, Ed., vol. 6558. Springer, 2011, pp. 121–141. [30] D. J. Bernstein, “Curve25519: New Diffie-Hellman speed records,” in Public Key Cryptography (PKC), 2006, pp. 207–228. [31] S. Goldwasser, S. Micali, and R. Rivest, “A digital signature scheme secure against adaptive chosen-message attacks,” SIAM Journal of Computing, vol. 17, no. 2, pp. 281–308, April 1988. [32] J.-S. Coron, Y. Dodis, C. Malinaud, and P. Puniya, “Merkle-Damgard˚ revisited: How to construct a hash function,” in Advances in Cryptology (CRYPTO), ser. Lecture Notes in Computer Science, vol. 3621. Springer, 2005, pp. 430–448. [33] M. Bellare, “New proofs for NMAC and HMAC: Security without collision-resistance,” in Advances in Cryptology (CRYPTO), ser. Lecture Notes in Computer Science, C. Dwork, Ed., vol. 4117. Springer, 2006, pp. 602–619. [34] D. A. McGrew and J. Viega, “The security and performance of the Galois/Counter Mode (GCM) of operation,” in Progress in Cryptology - INDOCRYPT 2004, ser. Lecture Notes in Computer Science, A. Canteaut and K. Viswanathan, Eds., vol. 3348. Chennai, India: Springer, Dec. 2004, pp. 343–355. [35] P.Rogaway, “Authenticated-encryption with associated-data,” in Ninth ACM Conference on Computer and Communications Security (CCS-9). Washington, DC: ACM Press, Nov. 2002, pp. 98–107. [36] Open Whisper Systems, “Signal for the browser,” 2015, https://github.com/WhisperSystems/Signal-Browser. [37] GitHub, “Electron framework,” 2016, http://electron.atom.io/. [38] M. Avalle, A. Pironti, R. Sisto, and D. Pozza, “The Java SPI framework for security protocol implementation,” in Availability, Reliability and Security (ARES), 2011 Sixth International Conference on, Aug 2011, pp. 746–751. [39] G. Bierman, M. Abadi, and M. Torgersen, “Understanding TypeScript,” in ECOOP 2014 Object-Oriented Programming, ser. Lecture Notes in Computer Science, R. Jones, Ed., vol. 8586. Springer, 2014, pp. 257–281. [40] Facebook Inc., “Flow, a static type checker for JavaScript,” http://flowtype.org/docs/about-flow.html. [41] C. Fournet, N. Swamy, J. Chen, P.-E. Dagand, P.-Y. Strub, and B. Livshits, “Fully abstract compilation to JavaScript,” SIGPLAN Not., vol. 48, no. 1, pp. 371–384, Jan. 2013. [Online]. Available: http://doi.acm.org/10.1145/2480359.2429114 [42] C. Bansal, K. Bhargavan, A. Delignat-Lavaud, and S. Maffeis, “Discovering concrete attacks on website authorization by formal analysis,” Journal of Computer Security, vol. 22, no. 4, pp. 601–657, 2014. [43] G. Bai, J. Lei, G. Meng, S. S. Venkatraman, P. Saxena, J. Sun, Y. Liu, and J. S. Dong, “AUTHSCAN: automatic extraction of web authentication protocols from implementations,” in Network and Distributed System Security Symposium (NDSS), 2013. [44] D. Fett, R. Kusters,¨ and G. Schmitz, “An Expressive Model for the Web Infrastructure: Definition and Application to the BrowserID SSO System,” in 35th IEEE Symposium on Security and Privacy (S&P 2014). IEEE Computer Society, 2014, pp. 673–688. [45] K. Cohn-Gordon, C. Cremers, and L. Garratt, “On post-compromise security,” in IEEE Computer Security Foundations Symposium (CSF), 2016, pp. 164–178. [46] K. Cohn-Gordon, C. Cremers, B. Dowling, L. Garratt, and D. Stebila, “A formal security analysis of the signal messaging protocol,” in IEEE European Symposium on Security and Privacy (Euro S&P), 2017. [47] Y. Dodis, T. Ristenpart, J. Steinberger, and S. Tessaro, “To hash or not to hash again? (In)differentiability results for H2 and HMAC,” in Advances in Cryptology (Crypto), 2012, pp. 348–366. 47 Deliverable D4.2 NEXTLEAP Grant No. 688722

A. ProScript to ProVerif Translation Samples

1 free io:channel. 2 type number. type function. type key. [...] 3 const string_63:bitstring[data].(* WhisperMessageKeys*) 4 [...] 5 equation foralla:key,b:key; 6 PS_crypto_DH25519(b, PS_crypto_DH25519(a, key_83)) = 7 PS_crypto_DH25519(a, PS_crypto_DH25519(b, key_83)). 8 fun PS_crypto_AESCTREncrypt(key, iv, bitstring):bitstring. 9 reduc forallk:key,i:iv,m:bitstring; PS_crypto_AESCTRDecrypt( 10k,i, PS_crypto_AESCTREncrypt(k,i,m)) =m. 11 [...] 12 letfun fun_AKEResponse(me:me, them:them, msg:msg) = 13 lete= PS_crypto_random32Bytes(string_80) in let ge= PS_crypto_DH25519(e, key_83) in 14 let shared= fun_TDH0(keypair_get_priv(me_get_identity(me)),e, them_get_identity(them), msg_get_prekey(msg), msg_get_ephemeral(msg)) in 15 let recvKeys= fun_HKDF(shared, Type_key_construct(), string_56) in 16 let validSig= PS_crypto_checkED25519(them_get_identity(them), Type_key_toBitstring(msg_get_prekey(msg)), msg_get_prekeySig(msg)) in 0 [...] 17 free secMsg1:bitstring[private]. free secMsg2:bitstring[private]. 18 query attacker(secMsg1). query attacker(secMsg2). 19 noninterf secMsg1. noninterf secMsg2. 20 event Send(key, key, bitstring). event Recv(key, key, bitstring). 21 querya:key,b:key,m:bitstring; event(Recv(a,b,m)) = event(Send(a,b,m)). 22 [...] ⇒ 23 let Alice(me:me, them:them) = 24 let aStartSession= fun_startSession(me, them) in 25 let them= sendoutput_get_them(aStartSession) in 26 out(io, sendoutput_get_output(aStartSession)); 27 in(io, bAcceptSession:msg); 28 let aAcceptSession= fun_recv(me, them, bAcceptSession) in 29 let them= recvoutput_get_them(aAcceptSession) in 30 let encMsg1= fun_send(them, secMsg1) in 31 let them= sendoutput_get_them(encMsg1) in 32 event Send(keypair_get_pub(me_get_identity(me)), them_get_identity(them), secMsg1); 33 out(io, sendoutput_get_output(encMsg1)); 34 phase 1; out(io, keypair_get_priv(me_get_identity(me))); in(io, encMsg2:msg); 35 let decMsg2= fun_recv(me, them, encMsg2) in 36 if(msg_get_valid(recvoutput_get_output(decMsg2)) = true) then( 37 let msg2= recvoutput_get_plaintext(decMsg2) in 38 event Recv(them_get_identity(them), keypair_get_pub(me_get_identity(me)), msg2) 39 ). 40 let Bob(me:me, them:them) = [...] 41 let AliceM(me:me, them:them) = [...] 42 let BobM(me:me, them:them) = [...] 43 process 44 let alice= fun_newIdentity() in let bob= fun_newIdentity() in let mallory= fun_newIdentity() in 45 out(io, mallory); 46 let bobsAlice = [...] in let alicesMallory = [...] in let bobsMallory = [...] 47 (Alice(alice, alicesBob) | Bob(bob, bobsAlice) | AliceM(alice, alicesMallory) | BobM(bob, bobsMallory))

Figure 8: Extracted model with types, equations between primitives and human-readable protocol functionality.

48 Deliverable D4.2 NEXTLEAP Grant No. 688722

1 const Type_key={ 2 construct: function() { 3 return [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4 0x00, 0x00, 0x00, 0x00. 0x00, 0x00, 0x00, 0x00, 5 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] 7 }, 8 assert: function(a){ 9 vari = 0; for(i = 0;i < 32;i++) { 10a[i&31] & 0x00}; returna 11 }, 12 [...] 13 } 14 [...] 15 const RATCHET={ 16 deriveSendKeys: function(them, newEphemeralPriv){ 17 const kShared= ProScript.crypto.DH25519(newEphemeralPriv, them.ephemeral) 18 const sendKeys= UTIL.HKDF(kShared, them.recvKeys[0],’WhisperRatchet’) 19 const kKeys= UTIL.HKDF( 20 ProScript.crypto.HMACSHA256(sendKeys[1],’1’), 21 Type_key.construct(),’WhisperMessageKeys’ 22 ) 23 return{ 24 sendKeys: sendKeys, recvKeys: them.recvKeys, 25 kENC: kKeys[0], kMAC: kKeys[1] 26 } 27 }, 28 deriveRecvKeys: function(them, newEphemeralPub) { [...] } 29 } 30 [...] 31 const TextSecure={ 32 newIdentity: function() { [...] }, 33 startSession: function(me, them){ 34 var me= Type_me.assert(me) 35 var them= Type_them.assert(them) 36 return{ 37 them: them, 38 output:{ 39 status: 1, 40 valid: true, 41 prekey: Type_key.construct(), 42 ephemeral: Type_key.construct(), 43 [...] 44 } 45 } 46 }, 47 acceptSession: function(me, them, msg) { [...] }, 48 send: function(them, plaintext) { [...] }, 49 recv: function(me, them, msg){ 50 var me= Type_me.assert(me) 51 var them= Type_them.assert(them) 52 var msg= Type_msg.assert(msg) 53 const themMsg={them: them, msg: msg} 54 if((msg.status === 2) && (them.status === 0)) { 55 return recvHandlers.AKEResponse(me, them, msg) 56 } 57 else if((msg.status === 3) && (them.status === 2)) { 58 return recvHandlers.message(recvHandlers.completeAKE(me, them, msg)) 59 } 60 else if((msg.status === 3) && (them.status === 3)) { 61 return recvHandlers.message(themMsg) 62 } 63 else{ return{ 64 them: Type_them.construct(), output: Type_msg.construct(), plaintext:’’ 65 }} 66 } 67 }

Figure 9: SP functionality is written in ProScript’s idiomatic style which employs JavaScript’s purely functional programming language features.

49 Deliverable D4.2 NEXTLEAP Grant No. 688722

B. ProScript Operational Semantics

Notation: Sorts and Constants. x X U User variable names. ∈ @proto,@this,@scope,@body X I Internal variables. { } ∈ x X X I X U Variable names. ∈ , ∗

l Lnull L null Locations. ∈ , ∪ { }

lop Object.prototype.

lg Global object.

L C L Scope chains. ∈ , ∗ n N Numbers. ∈ s S Strings. ∈ undefined U Undefined. ∈ e E Expressions. ∈ l x R References. · ∈ λx e F Function code. · ∈ p P X U S Property names. ∈ , ∪ v V U N S U null User values. ∈ , ∪ ∪ ∪ { } U v V V Lnull C F Semantic values. ∈ , ∪ ∪ ∪ H L X V Heaps. ∈ × → Notation: Functions and Judgements. σ(H,L,x) Find defining scope. π(H,L,x) Prototype resolution. γ(H,r) Dereferencing values.

True(E) E is true. False(E) E is false.

obj(l,l0) Empty object at l. fun(l,L,x,e,l0) New function at l. act(l,x,v,l0,e,l00) Activation object template. defs(x,l,e) Allocate local variable.

Scope Resolution: σ(H,L,x). π(H,l,x) = null σ(H,[],x) , null 6 σ(H,l : L,x) , l π(H,l,x) = null σ(H,l : L,x) , σ(H,L,x) Prototype Resolution: π(H,L,x). (l,x) dom(H) π(H,null,x) , null ∈ π(H,l,x) , l

50 Deliverable D4.2 NEXTLEAP Grant No. 688722

(l,x) / dom(H) H(l,@proto) = l ∈ 0 π(H,l,x) , π(H,l0,x) Dereferencing Values: γ(H,r). π(H,l,x) = null r = l x l = null 6 · 6 γ(H,r) r γ(H,l x) undefined , · , π(H,l,x) = l0 l = null 6 γ(H,l x) H(l ,x) · , 0 Auxiliary Predicates. True(E) E / 0,””,null,undefined , ∈ { } False(E) E 0,””,null,undefined , ∈ { } obj(l,l ) (l,@proto) l 0 , 7→ 0 fun(F,Closure,Var,Body,Proto) , (F,@scope) Closure (F,@body) λVar.Body 7→ ∗ 7→ ∗ (F,prototype) Proto (F,@proto) 7→ ∗ act(l,x,v,e,l ) l 00 , 7→ x : v,@this : l ,@proto : null defs(x,l,e) { 00 } ∗ Local Variable Definition. x = y 6 defs(x,l,var y) (l,y) undefined , 7→ defs(x,l,e1 = e2) , defs(x,l,e1) defs(x,l,e1;e2) defs(x,l,e1) defs(x,l,e2) , ∪ defs(x,l,if(e1) e2 e3 ) defs(x,l,e2) defs(x,l,e3) { }{ } , ∪ otherwise defs(x,l,e) , emp Syntax of Terms: v, e. v ::= n m undefined null | | |  e;e x v if(e) {e}{e} var x | | | | e ::= const x e e e.x e(e) x = e  | function(x)e| ⊕ {x| :e ...x| :e }| e[e] | | 1 1 n n |   Operational Semantics: H,L,e H ,r. −→ 0 Definition H,L,(var const) x H,undefined | −→

Value H,L,v H,v −→

H,L,e H ,l −→ 0 0 γ(H0,l0 x) = v MemberAccess · H,L,e.x H ,v −→ 0

σ(H,L,x) = l0 γ(H,l0 x) = v Variable · H,L,x H,v −→ 51 Deliverable D4.2 NEXTLEAP Grant No. 688722

H = H obj(l ,l ) 0 ∗ 0 op Hi 1,L,ei Hi0,vi i 1..n. − −→ ∀ ∈ Hi = Hi0[(l0,xi) vi] Object  →  H,L,{x :e ,...,x :e } H ,l 1 1 n n −→ n 0

σ(H,L,x) l0 H,L,e −→H ,v −→ 0 H00 = H0[(l0,x) v] Assignment → H,L,x = e H ,v −→ 00

H,L,e H ,v 1 −→ 0 H0,L,e2 H00,v0 Sequence −→ H,L,e ; e H ,v 1 2 −→ 00 0

H,L,e1 H0,v1 H ,L,e −→ H ,v 0 2 −→ 00 2 v1 v2 = v BinaryOperators ⊕ H,L,e e H ,v 1 ⊕ 2 −→ 00

H,L,e H ,l 1 −→ 1 0 l0 = null H ,L,e6 H ,p 1 2 −→ 0 γ(H0,l0 p) = v ComputedAccess · H,L,e [e ] H ,v 1 2 −→ 0

H0 = H obj(l,lop) fun(l0,L,x,e,l) Function ∗ ∗ H,L,function(x) e H ,l { } −→ 0 0

H,L,e H ,l 1 −→ 1 1 H1(l1,@body) = λ x.e3 H1(l1,@scope) = L0 H ,L,e H ,v 1 2 −→ 2 H3 = H2 act(l,x,v,e3, ) H3,l : L0,e3 H0,v0 FunctionCall ∗ ⊥ −→ H,L,e (e ) H ,v 1 2 −→ 0 0

H,L,e1 H0,v True(v) H0,L,e2 H00,v0 IfTrue −→ −→ H,L,if(e ) e e H ,v 1 { 2}{ 3} −→ 00 0

H,L,e1 H0,v False(v) H0,L,e3 H00,v0 IfFalse −→ −→ H,L,if(e ) e e H ,v 1 { 2}{ 3} −→ 00 0

C. CryptoVerif: Indifferentiability of HKDF

We start from the assumption that the compression function underlying SHA256 is a random oracle, and show that the functions

x ,x ,x ,x HKDF(c x x x x ,c ,c ) 1 2 3 4 7→ 0k 1k 2k 3k 4 1 2 x ,x ,x HKDF(c x x x ,c ,c ) 1 2 3 7→ 0k 1k 2k 3 1 2 x,y HKDF(x,y,c ) 7→ 2 x HKDF(x,c ,c ) 7→ 1 4 where c1 = 0 (256-bits), c2 = ”WhisperRatchet”, and c4 = ”WhisperMessageKeys”, can be considered as inde- pendent random oracles; more formally, we show that they are indifferentiable [32] from independent random oracles. 52 Deliverable D4.2 NEXTLEAP Grant No. 688722

Definition 1 (Indifferentiability). A function F with oracle access to a random oracle H is (tD,tS,q,ε)-indifferentiable from a random oracle H0 if there exists a simulator S such that for any distinguisher D

Pr[DF,H = 1] Pr[DH0,S = 1] ε | − |≤

The simulator S has oracle access to H0 and runs in time tS. The distinguisher D runs in time tD and makes at most q queries. F,H In the game G0 = D , the distinguisher interacts with the real function F and the random oracle H from which H0,S F is defined. In the game G1 = D , the distinguisher interacts with a random oracle H0 instead of F, and with a simulator S, which simulates the behavior of the random oracle H using calls to H0. Indifferentiability means that these two games are indistinguishable.

Theorem 4.4 in [47] shows that HMAC-SHA256 is then indifferentiable from a random oracle, provided the MAC keys are less than the block size of the hash function minus one, which is true here: the block size of SHA256 is 512 bits and the MAC keys are 256-bit long.

In the four calls to HKDF that we consider, we did not make explicit the length of the returned key material. This length is at most 512 bits, so we can consider that HKDF is defined by truncation of the following function HKDF2 to the desired length:

HKDF (salt,key,info) = K K where 2 1k 2 prk = HMAC(salt,key) (3) K = HMAC(prk,info 0x00) 1 k K = HMAC(prk,K info 0x01) 2 1k k and HKDF(key,salt,info) is a truncation of HKDF2(salt,key,info). Much like for HMAC in [47], this function is not indifferentiable from a random oracle in general. Intuitively, the problem comes from a confusion between the first and the second (or third) call to HMAC, which makes it possible to generate prk by calling HKDF2 rather than HMAC. In more detail, let

prk = HKDF (s,k,i) k 2 salt = HMAC(s,k) x = HMAC(prk,info 0x00) k x0 = HKDF (salt,i 0x00,info) k 2 k where the notation x x = HKDF (s,k,i) denotes that x consists of the first 256 bits of HKDF (s,k,i) and x 1k 2 2 1 2 2 its last 256 bits.

When HKDF is defined from HMAC as above, we have prk = HMAC(prk0,i 0x00) where prk0 = HMAC(s,k) = 2 k salt, so prk = HMAC(salt,i 0x00). Hence, x = HMAC(prk,info 0) = x. However, when HKDF is a random k 0 k 2 oracle and HMAC is defined from HKDF2, the simulator that computes HMAC sees what seems to be two unrelated calls to HMAC. (It is unable to see that prk is in fact related to the previous call salt = HMAC(s,k): we have prk = HKDF (s,k,i) but the simulator does not know which value of i it should use.) Therefore, the k 2 simulator can only return fresh random values for salt and x, and x = x in general. 6 0 We can however recover the indifferentiability of HKDF2 under the additional assumption that the three calls to HMAC use disjoint domains. Let S, K , and I be the sets of possible values of salt, key, and info respectively, and M the set of 256-bit bitstrings, output of HMAC. Lemma 1. If K (I 0x00 M I 0x01) = 0/ and S consists of bitstrings of 256 bits, then HKDF with domain ∩ k ∪ k k 2 S K I is (t ,t ,q,ε)-indifferentiable from a random oracle, where ε = O(q2/ M ) and t = O(q2), and O × × D S | | S just hides small constants.

Proof. Consider

the game G in which HMAC is a random oracle and HKDF is defined from HMAC by (3), and • 0 2 53 Deliverable D4.2 NEXTLEAP Grant No. 688722

the game G in which HKDF is a random oracle and HMAC is defined as follows. • 1 2 Let L be a list of pairs ((k,m),r) such that r is the result of a previous call to HMAC(k,m). The list L is initially empty. HMAC(k,m) =

1. if ((k,m),r) L for some r, then return r, else ∈ 2. if ((k ,m ),k) L for some k S and m K , and m = info 0x00 for some info I , then let r = 0 0 ∈ 0 ∈ 0 ∈ k ∈ k HKDF2(k0,m0,info), else 3. if ((k ,m ),k) L for some k S and m K , and m = k info 0x01 for some k M and info I , 0 0 ∈ 0 ∈ 0 ∈ 1k k 1 ∈ ∈ then let k k = HKDF (k ,m ,info); if k = k , then r = k ; 10 k 20 2 0 0 10 1 20 4. otherwise, let r be a fresh random element of M ; 5. add ((k,m),r) to L;

6. return r.

We name direct oracle calls to HKDF2 or HMAC calls that are done directly by the distinguisher, and indirect oracle calls the calls to HMAC done from inside HKDF2 (in G0) and the calls to HKDF2 done from inside HMAC (in G1).

Let us show that these two games are indistinguishable as long as, in G0, H1. HMAC never returns the same result for different arguments,

H2. no fresh result of HMAC is equal to the first argument of a previous call to HMAC,

H3. the distinguisher never calls HMAC(k,m) where k = HMAC(salt,key) has been called from inside HKDF2 but not directly by the distinguisher,

H4. and HMAC(prk,info 0x00) never returns a fresh k such that HMAC(prk,k info 0x01) has been called k 1 1k k (directly or indirectly) before,

and in G1, H5. there are no two elements ((k,m),r) and ((k ,m ),r) in L with (k,m) = (k ,m ), 0 0 6 0 0 H6. if the distinguisher calls HMAC(prk,k info 0x01) with ((salt,key),prk) L and k = HKDF (salt,key,info), 1k k ∈ 1k 2 then HKDF (salt,key,info) has been called (directly or indirectly at step 2) before the call to HMAC(prk,k info 0x01). 2 1k k We have the following invariant:

P1. Given salt,key, there is at most one prk such that ((salt,key),prk) L. ∈ Indeed, when L contains such an element, calls to HMAC(salt,key) immediately return prk at step 1, and never add another element ((salt,key),prk0) to L.

Case 1. Suppose the distinguisher makes a direct oracle call to HKDF2 or HMAC with the same arguments as a previous direct call to the same oracle. Both G0 and G1 return the same result as in the previous call.

Case 2. Suppose the distinguisher makes a direct call to HMAC(k,m) with arguments that do not occur in a previous direct call to HMAC.

Case 2.a) In G0, this HMAC call has already been done as HMAC(salt,key) from inside HKDF2. In G0, the result is prk = HMAC(salt,key), which is independent from previously returned values, so it looks like a fresh random value to the distinguisher. In G , we cannot have m = info 0x00 nor m = k info 0x01 because 1 k 1k k m = key K which is disjoint from I 0x00 and from M I 0x01, so HMAC returns a fresh random value. ∈ k k k Case 2.b) In G , this HMAC call has already been done as HMAC(prk,info 0x00) from inside HKDF (salt,key,info). 0 k 2 Hence HMAC(k,m) = HMAC(prk,info 0x00) is the first 256 bits of HKDF (salt,key,info) and prk = HMAC(salt,key). k 2 54 Deliverable D4.2 NEXTLEAP Grant No. 688722

Since by H3, the distinguisher never calls HMAC(k,m) where k = HMAC(salt,key) has been called from inside HKDF2 but not directly by the distinguisher, HMAC(salt,key) has been called directly by the distinguisher. In G , since HMAC(salt,key) has been called, ((salt,key),prk) L, so HMAC(k,m) = HMAC(prk,info 0x00) 1 ∈ k returns the first 256 bits of HKDF2(salt,key,info) (step 2), as in G0. Case 2.c) In G , this HMAC call has already been done as HMAC(prk,K info 0x01) from inside HKDF (salt,key,info). 0 1k k 2 Hence HMAC(k,m) = HMAC(prk,K info 0x01) is the last 256 bits of HKDF (salt,key,info), prk = HMAC(salt,key), 1k k 2 and K = HMAC(prk,info 0x00) is the first 256 bits of HKDF (salt,key,info). As above, HMAC(salt,key) has 1 k 2 been called directly by the distinguisher. In G , since HMAC(salt,key) has been called, ((salt,key),prk) L, 1 ∈ so, since K is the first 256 bits of HKDF (salt,key,info), HMAC(k,m) = HMAC(prk,K info 0x01) returns 1 2 1k k the last 256 bits of HKDF2(salt,key,info) (step 3), as in G0.

Case 2.d) In G0, this HMAC call has never been done, directly or indirectly. Hence, HMAC returns a fresh ran- dom value. In G , if ((salt,key),k) L, then HMAC may return the first or last 256 bits of HKDF (salt,key,info). 1 ∈ 2 However, since HMAC(k,m) has not been called from HKDF2 in G0, HKDF2(salt,key,info) has not been called directly by the distinguisher, so the result of HMAC always looks like a fresh random value to the distinguisher.

Case 3. Suppose the distinguisher makes a direct call to HKDF2(salt,key,info) with arguments that do not occur in a previous direct call to HKDF2. Case 3.a) In G , this call to HKDF has already been done from HMAC. Hence ((salt,key),prk) L and 1 2 ∈ HMAC(prk,info 0x00) or HMAC(prk,k info 0x01) has been called. Since ((salt,key),prk) L, HMAC(salt,key) k 1k k ∈ has been called before the call to HMAC(prk,info 0x00) or HMAC(prk,k info 0x01), and it has returned prk. k 1k k Case 3.a) i) Suppose that HMAC(prk,info 0x00) has been called and it returned k , and HMAC(prk,k info 0x01) k 10 10 k k has not been called. By step 2 of the definition of HMAC in G1, since by H5, the only element of L of the form ( ,prk) is ((salt,key),prk), HMAC(prk,info 0x00) is the first 256 bits of a previous call to HKDF (salt,key,info). k 2 The current call to HKDF (salt,key,info) returns the same result, to its first 256 bits are HMAC(prk,info 0x00). 2 k Its last 256 bits are independent from returned random values. Indeed, if a call to HMAC returns the last 256 bits of HKDF2(salt,key,info), then this call occurs in step 3 of HMAC, and it is HMAC(prk0,m) with ((salt,key),prk0) L, m = k info 0x01, and k is the first 256 bits of HKDF (salt,key,info). By P1, prk0 = prk. ∈ 100k k 100 2 We have k = k , so HMAC(prk0,m) is HMAC(prk,k info 0x01). But HMAC(prk,k info 0x01) has not 10 100 10 k k 10 k k been called by hypothesis, so no previous call to HMAC returns the last 256 bits of HKDF2(salt,key,info). So the last 256 bits of HKDF2(salt,key,info) look like a fresh random value. In G , the first 256 bits of HKDF (salt,key,info) are also HMAC(prk,info 0x00), where prk = HMAC(salt,key). 0 2 k Furthermore, the last 256 bits of HKDF2(salt,key,info) are independent of previously returned values. Indeed, HMAC(prk,k info 0x01) has not been called directly. Furthermore, it has not been called from previous calls 10 k k to HKDF , because, if HMAC(prk,k info 0x01) had been called from HKDF (salt0,key0,info0), then by K 2 10 k k 2 ∩ (I 0x00 M I 0x01) = 0/, this call would be the last of the three calls to HMAC in HKDF (salt0,key0,info0), k ∪ k k 2 prk = HMAC(salt0,key0), and info0 = info. Since by H1, HMAC never returns the same result for different argu- ments, this would imply salt0 = salt and key0 = key, contradicting that HKDF2(salt,key,info) has not been called before. Therefore, the last 256 bits of HKDF2(salt,key,info) look like a fresh random value. Case 3.a) ii) Suppose that HMAC(prk,info 0x00) has been called and it returned k , and HMAC(prk,k info 0x01) k 10 10 k k has been called. By definition of HMAC in G , HMAC(prk,info 0x00) is the first 256 bits of HKDF (salt,key,info) 1 k 2 (step 2) and HMAC(prk,k info 0x01) is its last 256 bits (step 3), so HKDF (salt,key,info) = k k where 10 k k 2 10 k 20 k = HMAC(prk,info 0x00) and k = HMAC(prk,k info 0x01). In G , we have the same property by defini- 10 k 20 10 k k 0 tion of HKDF2. Case 3.a) iii) Otherwise, HMAC(prk,info 0x00) has not been called. k If HKDF2(salt,key,info) had been called from step 2 of HMAC, then we would have called HMAC(prk0,m) with ((salt,key),prk0) L and m = info 0x00. Furthermore, by P1, prk0 = prk, so we would have called ∈ k HMAC(prk,info 0x00). Contradiction. So HKDF (salt,key,info) has not been called from step 2 of HMAC. k 2

55 Deliverable D4.2 NEXTLEAP Grant No. 688722

Therefore, HKDF2(salt,key,info) has been called from step 3 of HMAC. If HKDF2(salt,key,info) had been called at step 3 of HMAC and its last 256 bits were returned, then the distinguisher would have called HMAC(prk0,k info 0x01) 10 k k with ((salt,key),prk0) L and k = HKDF (salt,key,info). By H6, HKDF (salt,key,info) would have been ∈ 10 k 2 2 called before, either directly (excluded by hypothesis) or indirectly at step 2. Then the distinguisher would have called HMAC(prk00,info 0x00) with ((salt,key),prk0) L, so by P1, prk00 = prk, so this is excluded by hypoth- k ∈ esis. Therefore, the last 256 bits of HKDF2(salt,key,info) were not returned at step 3.

We can then conclude that in G1, the value of HKDF2(salt,key,info) is independent from previously returned values, so it looks like a fresh random value.

In G , HMAC(salt,key) has been called directly and returned prk, HMAC(prk,info 0x00) has not been called 0 k directly. If a previous call to HKDF (salt0,key0,info0) called HMAC(prk,info 0x00), then we would have info0 = 2 k info and prk = HMAC(salt0,key0). By H1, this would imply salt0 = salt and key0 = key, so HKDF2(salt,key,info) would have been called before, which is excluded by hypothesis. Therefore, HMAC(prk,info 0x00) has not k been called before, directly or indirectly. By H4, HMAC(prk,k info 0x01) has not been called before, with 1k k k = HMAC(prk,info 0x00). Therefore, HMAC(prk,info 0x00) and HMAC(prk,k info 0x01) have not been 1 k k 1k k called before, so their result is independent from previously returned values. Hence HKDF2(salt,key,info) is independent from previously returned values, as in G1.

Case 3.b) In G1, this HKDF2 call has never been done, directly or indirectly. Hence HKDF2 returns a fresh random value. In G0, the result is obtained from calls to HMAC. The distinguisher has not made these calls to HMAC directly calling HMAC(salt,key) first, because otherwise the simulator for HMAC in G1 would have called HKDF2(salt,key,info). Furthermore, it cannot call HMAC(salt,key) with result prk after calling HMAC(prk,info 0x00) or HMAC(prk,k info 0x01) by H2. So the result of HKDF is independent of the k 1k k 2 result of direct HMAC calls made by the distinguisher. Moreover, other calls to HKDF2 did not generate the same last two calls to HMAC, because by H1, the first call to HMAC, HMAC(salt,key), never returns the same result for different arguments. So the result looks like a fresh random value to the distinguisher.

The previous proof shows that the games G0 and G1 are indistinguishable assuming the hypotheses H1–H6 hold. Let us bound the probability that they do not hold. Suppose that there are at most q (direct or indirect) queries to HMAC. The probability that H1 does not hold is at most the probability that among q random values in M , two of • them collide, so it is at most q2/ M . | | The probability that H2 does not hold is at most the probability that among q random values in M , one of • them is equal to one among the q first arguments of HMAC queries, so it is also at most q2/ M . | | When H3 does not hold, the distinguisher calls HMAC(k,m) for a value k that happens to be equal to • HMAC(salt,key), which is independent of the values the distinguisher has seen, since HMAC(salt,key) has not been called directly by the distinguisher. There are at most q values HMAC(salt,key), and the distinguisher has q attempts, so the probability that H3 does not hold is at most q2/ M . | | Similarly, when H4 does not hold, the fresh random value HMAC(prk,info 0x00) collides with a previously • k fixed k . There are at most q values HMAC(prk,info 0x00) and at most q values k , so the probability 1 k 1 that H4 does not hold is at most q2/ M . | | Let us show that, if the random values r chosen at step 4 are all distinct and distinct from first and second • halves of HKDF2 results used in HMAC, then H5 holds. The proof is by induction on the sequence of calls of HMAC. If ((k,m),r) is added to L and r comes from a result of HKDF2 at step 2 or 3, then k determines k0,m0 uniquely by induction hypothesis, and m determines info as well as which half of the result of HKDF2 is r, hence r is uniquely determined from k,m, and distinct from elements chosen at step 4 by hypothesis. If ((k,m),r) is added to L and r is chosen at step 4, then r is always distinct from elements already in L by hypothesis. This concludes the proof of our claim. From this claim, we can easily see that the probability that H5 does not hold is at most q2/ M . | | 56 Deliverable D4.2 NEXTLEAP Grant No. 688722

When H6 does not hold, the distinguisher calls HMAC(prk,k info 0x01) and k happens to be equal to • 1k k 1 the first 256 bits of HKDF2(salt,key,info) which is independent from values returned to the distinguisher. So the probability that H6 does not hold is at most q2/ M . | | Hence, the probability that the distinguisher distinguishes G from G is at most 6q2/ M . 0 1 | | The hypothesis of Lemma 1 is satisfied in our case because K consists of bitstrings of length 256 bits = 32 bytes or 3 32 = 96 bytes, I 0x00 consists of bitstrings of length at most 31 bytes and M I 0x01 consists of × k k k bitstrings of length between 33 and 63 bytes. Lemma 2. If H is a random oracle, then the functions H1,...,Hn defined as H on disjoint subsets D1,...,Dn of the domain D of H are (tD,tS,q,0)-indifferentiable from independent random oracles, where tS = O(q) assuming one can determine in constant time to which subset Di an element belongs.

Proof. Consider

the game G in which H is a random oracle, and H (x) = H(x) for each x D and i n, and • 0 i ∈ i ≤ the game G in which H ,... H are independent random oracles defined on D ,...,D respectively, and • 1 1 n 1 n H(x) = H (x) if x D for some i n, and H(x) = H (x) otherwise, where H is a random oracle of domain i ∈ i ≤ 0 0 D (D ... D ). \ 1 ∪ ∪ n It is easy to see that these two games are perfectly indistinguishable, which proves indifferentiability.

By combining Lemmas 1 and 2, we obtain that

x ,x ,x ,x HKDF (0,c x x x x ,c ) 1 2 3 4 7→ 2 0k 1k 2k 3k 4 2 x ,x ,x HKDF (0,c x x x ,c ) 1 2 3 7→ 2 0k 1k 2k 3 2 x,y HKDF (x,y,c ) 7→ 2 2 x HKDF (0,x,c ) 7→ 2 4 are indifferentiable from independent random oracles. The domains are disjoint because different constants c2 and c4 are used and furthermore, the three cases that use c2 differ by the length of their second argument (4 256 = 1024 bits plus the length of c for x ,x ,x ,x HKDF (0,c x x x x ,c ), 3 256 = 768 bits × 0 1 2 3 4 7→ 2 0k 1k 2k 3k 4 2 × plus the length of c for x ,x ,x HKDF (0,c x x x ,c ), and 256 bits for x,y HKDF (x,y,c )). 0 1 2 3 7→ 2 0k 1k 2k 3 2 7→ 2 2 Lemma 3. If H is a random oracle that returns bitstrings of length l, then the truncation of H to length l0 < l is (tD,tS,q,0)-indifferentiable from a random oracle, where tS = O(q).

Proof. Consider

the game G in which H is a random oracle, and H (x) is H(x) truncated to length l , and • 0 0 0 the game G in which H is a random oracle that returns bitstrings of length l and H(x) = H (x) H (x) where • 1 0 0 0 k 00 H is a random oracle that returns bitstrings of length l l . 00 − 0 It is easy to see that these two games are perfectly indistinguishable, which proves indifferentiability.

By combining Lemma 3 with the previous results, we conclude that

x ,x ,x ,x HKDF(c x x x x ,c ,c ) 1 2 3 4 7→ 0k 1k 2k 3k 4 1 2 x ,x ,x HKDF(c x x x ,c ,c ) 1 2 3 7→ 0k 1k 2k 3 1 2 x,y HKDF(x,y,c ) 7→ 2 x HKDF(x,c ,c ) 7→ 1 4 are indifferentiable from independent random oracles.

57 D4.2 NEXTLEAP Grant No. 688722

4 Noise (Network-level Encryption)

58 Deliverable D4.3 NEXTLEAP Grant No. 688722

1 Introduction

Popular Internet protocols such as SSH and TLS use similar cryptographic primitives: symmetric primitives, public key primitives, one-way hash functions and so forth. Protocol stages are also similarly organized, usually beginning with an authenticated key exchange (AKE) stage followed by a messaging stage. And yet, the design methodology, underlying state machine transitions and key derivation logic tend to be entirely different between protocols with nevertheless similar building blocks. The targeted effective security goals tend to be similar, so why can’t the same methodology be followed for everything else?

Standard protocols such as those mentioned above choose a specific set of key exchange protocols to satisfy some stated use-cases while leaving other elements, such as round trips and (notoriously) cipher suites up to the deployer. Specifications use protocol-specific verbose notation to describe the underlying protocol, to the extent that even extracting the core cryptographic protocol becomes hard, let alone analyzing and comparing different modes for security.

Using completely different methodologies to build protocols that nevertheless often share the same primitives and security goals is not only unnecessary, but provably dangerous. The Triple Handshake attack on TLS published in 2014 [1] is based on the same logic that made the attack [2] on the Needham-Schroeder protocol [3] possible almost two decades earlier.

The core protocol in TLS 1.2 was also vulnerable to a similar attack, but since the protocol itself is hidden within layers of packet formats and C-like pseudocode, it was difficult for the attack to be detected. However, upon automated symbolic verification [4, 5], the attack quickly appeared not just in TLS, but also in variants of SSH and IPsec. Flaws underlying more recent attacks such as Logjam [6] were known for years before they were observed when the vulnerable protocol was analyzed. Had these protocols differed only in terms of network messages while still using a uniform, formalized logic for internal key derivation and state machine transitioning designed based on the state of the art of protocol analysis, these attacks could have been avoided.

IK : s ← ... e,es,s,ss → e,ee,se ←

Figure 1: An example Noise Handshake Pattern, IK.

1.1 The Noise Protocol Framework

The Noise Protocol Framework [7], recently introduced by Trevor Perrin, aims to avert this problem by presenting a simple language for describing cryptographic network protocols. In turn, a large number of semantic rules extend this simple protocol description to provide state machine transitions, key derivation logic and so on. The goal is to obtain the strongest possible effective security guarantees for a given protocol based on its description as a series of network messages by deriving its other elements from a uniform, formally specified logic followed by all protocol designs.

In designing a new secure channel protocol using the Noise Protocol Framework, one only provides an input using the simple language shown in Fig. 1. As such, from the viewpoint of the protocol designer, Noise protocols can only differ in the number of messages, the types of keys exchanged and the sequence or occurrence of public key transmissions and Diffie-Hellman operations. Despite the markedly non-expressive syntax, however, the occurence and position of the “tokens” in each message pattern can trigger complex state machine evolutions for both parties, which include operations such as key derivation and transcript hash mixing. 59 Deliverable D4.3 NEXTLEAP Grant No. 688722

Let’s examine Fig. 1. Before the AKE begins, the responder shares his static public key. Then in the first protocol message, the initiator sends a fresh ephemeral key, calculates a Diffie-Hellman shared secret between her ephemeral key and the recipient’s public static key, sends her public static key and finally calculates a Diffie-Hellman shared secret between her static key and the responder’s public static key. The responder then answers by generating an ephemeral key pair and sending his ephemeral public key, deriving a Diffie-Hellman shared secret between his ephemeral key and the ephemeral key of the initiator and another Diffie-Hellman shared secret between his static key and the ephemeral key of the initiator. Both of these AKE messages can also contain message payloads, which, depending on the availability of sufficient key material, could be AEAD-encrypted (in this particular Noise Handshake Pattern, this is indeed the case).

As we can see, quite a few operations have occured in what would at first glance appear to be simple syntax for a simple protocol. Indeed, underlying these operations is a sophisticated state machine logic tasked with mixing all of the derived keys together, determining when it is safe (or possible) to send encrypted payloads and ensuring transcript consistency, among other things. This is the value of the Noise Protocol Framework: allowing the protocol designer to describe what they need their protocol to do fairly effectively using this simple syntax, and leaving the rest to a sturdy set of underlying rules.

1.2 Noise Explorer: Formal Verification for any Noise Handshake Pattern

Noise Explorer, the central contribution of this work, capitalizes on the strengths of the Noise Protocol - work in order to allow for automated protocol verification to no longer be limited only to monolithic, pre-defined protocols with their own notation. In this work, we formalize Noise’s syntax, semantics, state transitions and Noise Handshake Pattern validity rules. We then present translation logic to go from Noise Handshake Patterns directly into full symbolic models ready for automated verification using the ProVerif [8, 9] automatic protocol verifier.

This allows us to then construct Noise Explorer, an online engine that allows for designing, validating and subsequently generating crypto- IN : graphic models for the automated formal verification of any arbitrary e,s Noise Handshake Pattern. Models generated using Noise Explorer → allow for the verification of Noise-based secure channel protocols e,ee,se ← against a battery of comprehensive ProVerif queries. Noise Explorer also comes with the first compendium of formal verification results for Figure 2: An example Noise Hand- Noise Handshake Patterns, browsable online using an interactive web shake Pattern, IN. application that presents dynamically generated diagrams indicating every cryptographic operation and security guarantee relevant to ev- ery message within the Noise Handshake Pattern.

Noise Explorer can also automatically generate software implementations for arbitrary Noise Handshake Pat- terns in Go, a programming language that is currently highly popular in server use case scenarios where secure channel protocols are often deployed. Generated Go implementations are resistant to side channel attacks and are optimized for performance and memory efficiency.

1.3 Contributions

Formal semantics and validity rules for Noise Handshake Patterns. §2 introduces formal verification in the symbolic model using ProVerif, setting the stage for §3.

Translations from Noise Patterns to processes in the applied pi-calculus. §3 discusses automated trans- lations from valid Noise Handshake Patterns into a representation in the applied pi-calculus [10] which includes cryptographic primitives, state machine transitions, message passing and a top-level process illustrating live pro- tocol execution. We present the first formal semantics and validity rules (illustrated as typing inference rules) for 60 Deliverable D4.3 NEXTLEAP Grant No. 688722

Noise Handshake Patterns. This allows Noise Explorer to validate and separate sane Noise Handshake Patterns from invalid ones based on arbitrary input, and is the foundation of further contributions described below.

Noise Handshake Pattern security goals expressed as ProVerif queries. In §4, we model all five “confiden- tiality” security goals from the Noise Protocol Framework specification in the applied pi-calculus and extend the two “authentication” goals to four.

Formal verification results for 50 Noise Handshake Patterns in the Noise Protocol Framework specifica- tion. §5 sees all of the previous contributions come together to provide formal verification results for 50 Noise Handshake Patterns.1 We find that while most of the results match those predicted by the specification authors, our extended model for “authentication” queries allows for more nuanced results. Furthermore, in §6, we analyze unsafe Noise Handshake Patterns and discover a potential for forgery attacks should Noise Handshake Patterns not be followed properly.

Software implementation generation for arbitrary Noise Handshake Patterns. §7 discusses a new feature in Noise Explorer which allows for the automated generation of software implementations for any Noise Handshake Pattern.

This work represents the first comprehensive formal analysis of the Noise Protocol Framework. However, sub- stantial tangential work has occured centering on the WireGuard [11] VPN protocol, which employs the IKpsk2 Noise Handshake Pattern: Lipp [12] presented an automated computational proof of WireGuard, Donenfeld et al. [13] presented an automated symbolic verification of WireGuard and Dowling et al. [14] presented a hand proof of WireGuard. These analyses’ results on the IK handshake pattern were in line with those we found in our own symbolic analysis. Other work exists centering on the automated verification of modern protocols [15, 16].

2 Formal Verification in the Symbolic Model

The main goal of this work is to use the ProVerif automated protocol verifier to obtain answers to our formal verification queries. In this section, we describe the parts of ProVerif that are relevant to our analysis.

ProVerif uses the applied pi-calculus, a language geared towards the description of network protocols, as its input language. It analyzes described protocols under a Dolev-Yao model, which effectively mimics an active network attacker. ProVerif models are comprised of a section in which cryptographic protocol primitives and operations are described as funs or letfuns and a “top-level process” section in which the execution of the protocol on the network is outlined.

In ProVerif, messages are modeled as abstract terms. Processes can generate new nonces and keys, which are treated as atomic opaque terms that are fresh and unguessable. Functions map terms to terms. For example, encryption constructs a complex term from its arguments (key and plaintext) that can only be deconstructed by decryption (with the same key). The attacker is an arbitrary ProVerif process running in parallel with the protocol, which can read and write messages on public channels and can manipulate them symbolically. Parallel and unbounded numbers of executions of different parts of the protocol are supported.

In the symbolic model, cryptographic primitives are represented as “perfect black-boxes”; a hash function, for example, cannot be modeled to be vulnerable to a length extension attack (which the hash function SHA-1 is vulnerable to, for example.) Encryption primitives are perfect pseudorandom permutations. Hash functions are perfect one-way maps. It remains possible to build complex primitives such as authenticated encryption with associated data (AEAD) and also to model interesting use cases, such as a Diffie-Hellman exponentiation that obtains a shared secret that is outside of the algebraic group. However, in the latter case, such constructions cannot be based on on an algebra that includes the space of integers commonly considered when modeling these scenarios, since all messages are simply a combination of the core terms used to express primitives.

1Anyone can use Noise Explorer to increase this number by designing, validating and then automatically verifying their own Noise Handshake Pattern. 61 Deliverable D4.3 NEXTLEAP Grant No. 688722

2.1 Verification Context

All generated models execute the protocol in comprehensive formal verification context: a typical run includes a process in which Alice initiates a session with Bob, a process in which Alice initiates a session with Charlie, a process in which Bob acts a responder to Alice and a process in which Bob acts as a responder to Charlie. Charlie is a compromised participant whose entire state is controlled by the attacker. Each process in the top- level process are executed in parallel. The top-level process is executed in an unbounded number of sessions. Within the processes, transport messages are again executed in an unbounded number of sessions in both directions. Fresh key material is provided for each ephemeral generated in each session within the unbounded number of sessions: no ephemeral key reuse occurs between the sessions modeled.

2.2 Cryptographic Primitives

Noise Handshake Patterns make use of cryptographic primitives which in this work we will treat as constructions in the symbolic model. We consider the following cryptographic primitives:

• KP(): Generates a new Diffie-Hellman key pair consisting of a private key x and a public key gx.

• DH(x KP(),y): Derives a Diffie-Hellman shared secret between the private key within the key pair x ← and the public key y.

• E(k,n,ad, p): Encrypts and generates an authentication tag for plaintext p using key k and nonce n, optionally extending the authentication tag to cover associated data ad. The output is considered to be Authenticated Encryption with Associated Data (AEAD) [17].

• D(k,n,ad,c): Decrypts and authenticates ciphertext c using key k and nonce n. Associated data ad must also be included if it was defined during the encryption step for authentication to pass on both c and ad.

• R(k): Returns a new key by applying a pseudorandom function on k.

• H(d): A one-way hash function on data d.

• HKDF(ck,ik): A Hash-Based Key Derivation function [18] that takes keys (ck, ik) and outputs a triple of keys. In some instances, the third key output is discarded and not used. The function is similar to the original HKDF definition but with ck acting as the salt and with a zero-length “info” variable.

In ProVerif, Diffie-Hellman is implemented as a letfun that takes two key-type values (representing points on the Curve25519 [19] elliptic curve) along with an equation that essentially illustrates the Diffie-Hellman relationship gab = gba in the symbolic model.2 DH and KP (implemented as generate_keypair) are then implemented as letfuns on top of that construction:3 fun dhexp(key, key):key. equation forall a:key,b:key; dhexp(b, dhexp(a,g)) = dhexp(a, dhexp(b,g)).

Encryption is implemented as a function that produces a bitstring (representing the ciphertext) parametrized by a key, nonce, associated data and plaintext. Decryption is a reduction function that produces the correct plaintext only when the appropriate parameters are given, otherwise the process ends: fun encrypt(key, nonce, bitstring, bitstring):bitstring.

fun decrypt(key, nonce, bitstring, bitstring):aead reduc forall k:key,n:nonce, ad:bitstring, plaintext:bitstring; decrypt(k,n, ad, encrypt(k,n, ad, plaintext)) = aeadpack( true, ad, plaintext).

2Recall that, in the symbolic model, any arithmetic property such as additivity is not a given and must be modeled specifically. 3keypairpack and keypairunpack are a fun and reduc pair that allow compressing and decompressing a tuple of key values into a keypair-type value for easy handling throughout the model. Whenever the suffixes pack and unpack appear from now on, it is safe to assume that they function in a similar pattern. 62 Deliverable D4.3 NEXTLEAP Grant No. 688722

Finally, H and HMAC are implemented as one-way functions parametrized by two bitstrings (for ease of use in modeling in the case of H, and for a keyed hash representation in the case of HMAC) while HKDF is constructed on top of them.

2.3 ProVerif Model Components

In the ProVerif model of a Noise Handshake Pattern, there are nine components:

1. ProVerif parameters. This includes whether to reconstruct a trace and whether the attacker is active or passive.

2. Types. Cryptographic elements, such as keys and nonces, are given types. Noise Handshake Message state elements such as CipherStates, SymmetricStates and HandshakeStates (see §3) are given types as well as constructors and reductors.

3. Constants. The generator of the g Diffie-Hellman group, HKDF constants such as zero and the names of principals (Alice, indicating the initiator, Bob, indicating the recipient, and Charlie, indicating a compro- mised principal controlled by the attacker) are all declared as constants.

4. Bitstring concatenation. Functions are declared for bitstring concatenation, useful for constructing and destructing the message buffers involved in the Noise Protocol Framework’s WriteMessage and ReadMessage functions.

5. Cryptographic primitives. DH, KP, E, D, H and HKDF are modeled as cryptographic primitives in the symbolic model.

6. State transition functions. All functions defined for CipherState, SymmetricState and HandshakeState are implemented in the applied pi-calculus.

7. Channels. Only a single channel is declared, pub, representing the public Internet.

8. Events and queries. Here, the protocol events and security queries relevant to a particular Noise Hand- shake Pattern are defined. This includes the four authentication queries and five confidentiality queries discussed in §4.

9. Protocol processes and top-level process. This includes the WriteMessage and ReadMessage func- tion for each handshake and transport message, followed by the top-level process illustrating the live execution of the protocol on the network.

3 Representing Noise in the Applied Pi-Calculus

The Noise Protocol Framework [7] is restricted only to describing messages between two parties (initiator and responder), the public keys communicated and any Diffie-Hellman operations conducted. Messages are called Noise “Message Patterns”. They make up authenticated key exchanges, which are called Noise “Handshake Patterns”. Noise supports authenticated encryption with associated data (AEAD) and Diffie-Hellman key agree- ment. The Noise Protocol Framework does not currently support any signing operations.

The full description of a Noise-based secure channel protocol is contained within its description of a Noise Handshake Pattern, such as the one seen in Fig. 1. The initial messages within a Noise Handshake Pattern, which contain tokens representing public keys or Diffie-Hellman operations are called handshake messages. After handshake messages, transport messages may occur carrying encrypted payloads. Here is an overview of the tokens that may appear in a handshake message:

• e,s. The sender is communicating their ephemeral or static public key, respectively.

63 Deliverable D4.3 NEXTLEAP Grant No. 688722

Syntax k ::= public DH keys e ephemeral DH key s static DH key t ::= tokens k public DH key k1k2 shared DH secret (ee, es, se, or ss) psk pre-shared key p ::= pre-messages ε end of pre-message (empty) k, p pre-message with public DH key m ::= messages ε end of message (empty) t,m message with token hr ::= handshake (responder’s turn) ε end of handshake m h responder message, then initiator ←− i hi ::= handshake (initator’s turn) ε end of handshake m h initiator message, then responder −→ r n ::= noise patterns p p 1 2 h pre-messages, then handshake −→ ←− i Figure 3: Noise Handshake Pattern Syntax.

• ee,es,se,ss. The sender has locally calculated a new shared secret. The first letter of the token indicates the initiator’s key share while the second indicates the responder’s key share. As such, this token remains the same irrespective of who is sending the particular handshake message in which it occurs.

• psk. The sender is mixing a pre-shared key into their local state and the recipient is assumed to do the same.

Optionally, certain key materials can be communicated before a protocol session is initiated. A practical example of how this is useful could be secure messaging protocols, where prior knowledge of an ephemeral key pair could help a party initiate a session using a zero-round-trip protocol, which allows them to send an encrypted payload without the responder needing to be online.

These pre-message patterns are represented by a series of messages occuring before handshake messages. The end of the pre-message stage is indicated by a “. . . ” sign. For example, in Fig. 1, we see a pre-message pattern indicating that the initiator has prior knowledge of the responder’s public static key before initiating a protocol session.

3.1 Validating Noise Handshake Pattern Syntax

Noise Handshake Patterns come with certain validity rules:

• Alternating message directions. Message direction within a Noise Handshake Pattern must alternate (initiator responder, initiator responder), with the first message being sent by the initiator. → ← • Performing Diffie-Hellman key agreement more than once. Principals must not perform the same Diffie-Hellman key agreement more than once per handshake.

• Sending keys more than once. Principals must not send their static public key or ephemeral public key more than once per handshake. 64 Deliverable D4.3 NEXTLEAP Grant No. 688722

Validity Rules d ::= direction: left or right kd ΓΓ kd d m d| MsgKey 6∈ ∪ { } ` t¯ ::= k k k psk tokens w. DH keys d | 1 2 | Γ k,m Γ ::=t¯0,...,t¯n context: set of prior tokens ` {d }d k1 Γ k2 Γ k1k2 Γ tokens (m) , k k m e,s (m e,s ) ∈ ∈ d 6∈ { | ∈ ∩ { }} ∪ \{ }  Γ k1k2 m MsgDH ∪ { } ` d d Γ k k ,m Pre-Message Validity: Γ p ` 1 2 ` psk ΓΓ psk d m MsgPSK 6∈ ∪ { } ` PreEmpty d d Γ psk,m Γ ε ` d ` d d k ΓΓ k p Handshake Validity: Γ hi PreKey 6∈ ∪ { } ` ` Γ d k, p ` HSEmpty Γ ε Message Validity: Γ d m ` ` Γ m Γ tokens (m) hr HSMessageI ` ∪ m ` ss Γ se Γ se Γ ee Γ  Γ hr ∈ ⇒psk ∈ Γ e ∈ Γ⇒ ∈ ` −→ MsgEmpty ∈ ⇒ ∈ Γ m Γ tokens (m) hi HSMessageR Γ ε ` ∪ m `  ss Γ es Γ` es Γ ee Γ Γ hi ∈ ⇒ ∈  ∈ ⇒ ∈ ` ←− psk Γ e Γ Noise Pattern Validity: n MsgEmpty ∈ ⇒ ∈ ` Γ ε ` p p {} ` 1 {} ` 2 tokens (p1) tokens (p2) hi NoiseValid  ∪p p `  1 2 h ` −→ ←− i Figure 4: Noise Pattern Validity Rules

• Transport messages after handshake messages. Noise Handshake Patterns can only contain trans- port handshake messages at the very bottom of the pattern.

• Appropriate key share communication. Principals cannot perform a Diffie-Hellman operation with a key share that was not communicated to them prior.

• Unused key shares. Noise Handshake Patterns should not contain key shares that are not subsequently used in any Diffie-Hellman operation.

• Transport messages. Noise Handshake Patterns cannot consist purely of transport messages.

The Noise Handshake Pattern syntax is more formally described in Fig. 3, while validity rules are formalized in Fig. 4.

3.2 Local State

Each principal in a Noise protocol handshake keeps three local state elements: CipherState, SymmetricState and HandshakeState. These states contain each other in a fashion similar to a Russian Matryoshka doll, with HandshakeState being the largest element, containing SymmetricState which in turn contains CipherState.

• CipherState contains k (a symmetric key) and n (a nonce), used to encrypt and decrypt ciphertexts.

• SymmetricState contains a CipherState tuple (k,n), an additional key ck and a hash function output h.

• HandshakeState contains a SymmetricState along with additional local public keys (s,e) and remote public keys (rs,re).

65 Deliverable D4.3 NEXTLEAP Grant No. 688722

Each state element comes with its own set of state transformation functions. These functions are triggered by the occurence and position of tokens within a Noise Handshake Pattern. We present a description of the state transition functions as seen in the Noise Protocol Framework specification, but restricted to a representation that follows implementing Noise Handshake Patterns in the symbolic model.

3.2.1 CipherState

A CipherState comes with the following state transition functions:

• InitializeKey(key): Sets k = key. Sets n = 0.

• HasKey(): Returns true if k is non-empty, false otherwise.

• SetNonce(nonce): Sets n = nonce.

• EncryptWithAd(ad, p): If k is non-empty returns E(k,n,ad, p) then increments n. Otherwise re- turns p.

• DecryptWithAd(ad, c): If k is non-empty returns D(k,n,ad,c) then increments n. Otherwise re- turns c. n is not incremented if authenticated decryption fails.

• Rekey(): Sets k = R(k).

In ProVerif, InitializeKey simply returns a cipherstate-type value packed with the input key and a starting nonce. hasKey unpacks an input cipherstate and checks whether the key is defined. The rest of the functions are based on similarly evident constructions: letfun encryptWithAd(cs:cipherstate, ad:bitstring, plaintext:bitstring) = let (k:key,n:nonce) = cipherstateunpack(cs) in let e= encrypt(k,n, ad, plaintext) in let csi= setNonce(cs, increment_nonce(n)) in (csi,e).

letfun decryptWithAd(cs:cipherstate, ad:bitstring, ciphertext:bitstring) = let (k:key,n:nonce) = cipherstateunpack(cs) in let d= decrypt(k,n, ad, ciphertext) in let (valid:bool, adi:bitstring, plaintext:bitstring) = aeadunpack(d) in let csi= setNonce(cs, increment_nonce(n)) in (csi, plaintext, valid).

letfun reKey(cs:cipherstate) = let (k:key,n:nonce) = cipherstateunpack(cs) in let ki= encrypt(k, maxnonce, empty, zero) in cipherstatepack(bit2key(ki),n).

3.2.2 SymmetricState

A SymmetricState comes with the following state transition functions:

• InitializeSymmetric(name): Sets ck = h = H(name).

• MixKey(ik): Sets (ck,tk) = HKDF(ck,ik) and calls InitializeKey(tk).

• MixHash(data): Sets h = H(h data).4 k • MixKeyAndHash(ik): Sets (ck,th,tk) = HKDF(ck,ik), then calls MixHash(th) and InitializeKey(tk).

• GetHandshakeHash(): Returns h.

4 denotes bitstring concatenation. k 66 Deliverable D4.3 NEXTLEAP Grant No. 688722

• EncryptAndHash(p): Sets c = EncryptWithAd(h,p). Calls MixHash(c) and returns c.

• DecryptAndHash(c): Sets p = DecryptWithAd(h,c). Calls MixHash(c) and returns c and returns p.

• Split(): Sets (tk1,tk2) = HKDF(ck,zero). Creates two CipherStates (c1,c2). Calls c1.InitializeKey(tk1) and c2.InitializeKey(tk2). Returns (c1,c2), a pair of CipherStates for encrypting transport mes- sages.5

In ProVerif, these functions are implemented based on letfun declarations that combine previously declared funs and letfuns: letfun initializeSymmetric(protocol_name:bitstring) = let h= hash(protocol_name, empty) in let ck= bit2key(h) in let cs= initializeKey(bit2key(empty)) in symmetricstatepack(cs, ck,h). letfun mixKey(ss:symmetricstate, input_key_material:key) = let (cs:cipherstate, ck:key,h:bitstring) = symmetricstateunpack(ss) in let (ck:key, temp_k:key, output_3:key) = hkdf(ck, input_key_material) in symmetricstatepack(initializeKey(temp_k), ck,h). letfun mixHash(ss:symmetricstate, data:bitstring) = let (cs:cipherstate, ck:key,h:bitstring) = symmetricstateunpack(ss) in symmetricstatepack(cs, ck, hash(h, data)). letfun mixKeyAndHash(ss:symmetricstate, input_key_material:key) = let (cs:cipherstate, ck:key,h:bitstring) = symmetricstateunpack(ss) in let (ck:key, temp_h:key, temp_k:key) = hkdf(ck, input_key_material) in let (cs:cipherstate, temp_ck:key,h:bitstring) = symmetricstateunpack(mixHash(symmetricstatepack( cs, ck,h), key2bit(temp_h))) in symmetricstatepack(initializeKey(temp_k), ck,h). letfun getHandshakeHash(ss:symmetricstate) = let (cs:cipherstate, ck:key,h:bitstring) = symmetricstateunpack(ss) in (ss,h). letfun encryptAndHash(ss:symmetricstate, plaintext:bitstring) = let (cs:cipherstate, ck:key,h:bitstring) = symmetricstateunpack(ss) in let (cs:cipherstate, ciphertext:bitstring) = encryptWithAd(cs,h, plaintext) in let ss= mixHash(symmetricstatepack(cs, ck,h), ciphertext) in (ss, ciphertext). letfun decryptAndHash(ss:symmetricstate, ciphertext:bitstring) = let (cs:cipherstate, ck:key,h:bitstring) = symmetricstateunpack(ss) in let (cs:cipherstate, plaintext:bitstring, valid:bool) = decryptWithAd(cs,h, ciphertext) in let ss= mixHash(symmetricstatepack(cs, ck,h), ciphertext) in (ss, plaintext, valid). letfun split(ss:symmetricstate) = let (cs:cipherstate, ck:key,h:bitstring) = symmetricstateunpack(ss) in let (temp_k1:key, temp_k2:key, temp_k3:key) = hkdf(ck, bit2key(zero)) in let cs1= initializeKey(temp_k1) in let cs2= initializeKey(temp_k2) in (ss, cs1, cs2).

3.2.3 HandshakeState

A HandshakeState comes with the following state transition functions:

5zero is meant to denote a null bitstring. 67 Deliverable D4.3 NEXTLEAP Grant No. 688722

• Initialize(hp, i, s, e, rs, re): hp denotes a valid Noise Handshake Pattern. i is a boolean which denotes whether the local state belongs to the initiator. Static public keys (s,rs) may be left empty or may be pre-initialized in the event that any of them appeared in a pre-message. Calls InitializeSymmetric(hp.name). Calls MixHash() once for each public key listed in the pre-messages within hp.

• WriteMessage(p): Depending on the tokens present in the current handshake message, different operations occur:

– e: Sets e KP(). Appends ge to the return buffer. Calls MixHash(ge). ← – s: Appends EncryptAndHash(gs) to the buffer.

– ee: Calls MixKey(DH(e,re)).

– es: Calls MixKey(DH(e,rs)) if initiator, MixKey(DH(s,re)) if responder.

– se: Calls MixKey(DH(s,re)) if initiator, MixKey(DH(e,rs)) if responder.

– ss: Calls MixKey(DH(s,rs)).

Then, EncryptAndHash(p) is appended to the return buffer. If there are no more handshake messages, two new CipherStates are returned by calling Split().

• ReadMessage(m): Depending on the tokens present in the current handshake message, different operations occur:

– e: Sets re to the public ephemeral key retrieved from m.

– s: Sets temp to the encrypted public static key retrieved from m. Sets rs to the result of DecryptAndHash(temp), failing on authenticated decryption error.

– ee: Calls MixKey(DH(e,re)).

– es: Calls MixKey(DH(e,rs)) if initiator, MixKey(DH(s,re)) if responder.

– se: Calls MixKey(DH(s,re)) if initiator, MixKey(DH(e,rs)) if responder.

– ss: Calls MixKey(DH(s,rs)).

Then, DecryptAndHash is called on the message payload extracted from m. If there are no more hand- shake messages, two new CipherStates are returned by calling Split().

3.3 Dynamically Generating ReadMessage and WriteMessage Functions in the Applied Pi- Calculus

In Noise Explorer (our analysis framework for Noise Handshake Patterns), cryptographic primitives and state transition functions are included from a pre-existing set of Noise Protocol Framework ProVerif headers written as a part of this work and are not automatically generated according to a set of rules. Events, queries, protocol processes and the top-level process, however, are fully generated using translation rules that make them unique for each Noise Handshake Pattern.

In our generated ProVerif models, each handshake message and transport message is given its own WriteMessage and ReadMessage construction represented as letfuns. These functions are constructed to invoke the appro- priate state transition functions depending on the tokens included in the message pattern being translated. An example generated translation can be see in Fig. 5, which concerns the first message in IK (Fig. 1): e,es,s,ss. → The state transition rules described in Noise Protocol Framework specification are implicated by the tokens within the message pattern. By following these rules, Noise Explorer generates a symbolic model that implements the state transitions relevant to this particular message pattern. From the initiator’s side:

68 Deliverable D4.3 NEXTLEAP Grant No. 688722

1 letfun writeMessage_a(me:principal, them: 1 letfun readMessage_a(me:principal, them: principal, hs:handshakestate, payload: principal, hs:handshakestate, message: bitstring, sid:sessionid) = bitstring, sid:sessionid) = 2 let (ss:symmetricstate,s:keypair,e:keypair, 2 let (ss:symmetricstate,s:keypair,e:keypair, rs:key, re:key, psk:key, initiator:bool rs:key, re:key, psk:key, initiator:bool ) = handshakestateunpack(hs) in ) = handshakestateunpack(hs) in 3 let (ne:bitstring, ciphertext1:bitstring, 3 let (ne:bitstring, ciphertext1:bitstring, ciphertext2:bitstring) = (empty, empty, ciphertext2:bitstring) = deconcat3( empty) in message) in 4 let e= generate_keypair(key_e(me, them, sid) 4 let valid1= true in ) in 5 let re= bit2key(ne) in 5 let ne= key2bit(getpublickey(e)) in 6 let ss= mixHash(ss, key2bit(re)) in 6 let ss= mixHash(ss, ne) in 7 (* No PSK, so skipping mixKey*) 7 (* No PSK, so skipping mixKey*) 8 let ss= mixKey(ss, dh(s, re)) in 8 let ss= mixKey(ss, dh(e, rs)) in 9 let (ss:symmetricstate, plaintext1:bitstring, 9 let s= generate_keypair(key_s(me)) in valid1:bool) = decryptAndHash(ss, 10 let (ss:symmetricstate, ciphertext1:bitstring ciphertext1) in ) = encryptAndHash(ss, key2bit( 10 let rs= bit2key(plaintext1) in getpublickey(s))) in 11 let ss= mixKey(ss, dh(s, rs)) in 11 let ss= mixKey(ss, dh(s, rs)) in 12 let (ss:symmetricstate, plaintext2:bitstring, 12 let (ss:symmetricstate, ciphertext2:bitstring valid2:bool) = decryptAndHash(ss, ) = encryptAndHash(ss, payload) in ciphertext2) in 13 let hs= handshakestatepack(ss,s,e, rs, re, 13 if ((valid1&& valid2) && (rs= getpublickey( psk, initiator) in generate_keypair(key_s(them))))) then ( 14 let message_buffer= concat3(ne, ciphertext1, 14 let hs= handshakestatepack(ss,s,e, ciphertext2) in rs, re, psk, initiator) in 15 (hs, message_buffer). 15 (hs, plaintext2, true)).

Figure 5: The WriteMessage and ReadMessage letfun constructions for the first message in IK (Fig. 1), generated according to translation rules from Noise Handshake Pattern to ProVerif. The appro- priate state transition functions are invoked in accordance with the occurence and ordering of tokens in the message pattern.

• e: Signals that the initiator is sending a fresh ephemeral key share as part of this message. This token adds one state transformation to writeMessage_a: mixHash, which hashes the new key into the session hash.

• es: Signals that the initiator is calculating a Diffie-Hellman shared secret derived from the initiator’s ephemeral key and the responder’s static key as part of this message. This token adds one state transfor- mation to writeMessage_a: mixKey, which calls the HKDF using as input the existing SymmetricState key and DH(e,rs), the Diffie-Hellman share calculated from the initiator’s ephemeral key and the respon- der’s static key.

• s: Signals that the initiator is sending a static key share as part of this message. This token adds one state transformation to writeMessage_a: encryptAndHash is called on the static public key. If any prior Diffie- Hellman shared secret was established between the sender and the recipient, this allows the initiator to communicate their long-term identity with some degree of confidentiality.

• ss: Signals that the initiator is calculating a Diffie-Hellman shared secret derived from the initiator’s static key and the responder’s static key as part of this message. This token adds one state transformation to writeMessage_a: mixKey, which calls the HKDF function using, as input, the existing SymmetricState key, and DH(s,rs), the Diffie-Hellman share calculated from the initiator’s static key and the responder’s static key.

Message A’s payload, which is modeled as the output of the function msg_a(initiatorIdentity, responderIdentity, sessionId), is encrypted as ciphertext2. This invokes encryptAndHash, which performs AEAD encryption on the payload, with the session hash as the associated data (encryptWithAd) and mixHash, which hashes the encrypted payload into the next session hash.

On the receiver end:

• e: Signals that the responder is receiving a fresh ephemeral key share as part of this message. This token

69 Deliverable D4.3 NEXTLEAP Grant No. 688722

I1K : s ← ... e,es,s → e,ee ← se →

Figure 6: An example Noise Handshake Pattern, I1K. This is a deferred pattern based on IK, shown in Fig. 1.

adds one state transformation to readMessage_a: mixHash, which hashes the new key into the session hash.

• es: Signals that the responder is calculating a Diffie-Hellman shared secret derived from the initiator’s ephemeral key and the responder’s static key as part of this message. This token adds one state trans- formation to readMessage_a: mixKey, which calls the HKDF function using, as input, the existing Sym- metricState key, and DH(s,re), the Diffie-Hellman share calculated from the initiator’s ephemeral key and the responder’s static key.

• s: Signals that the responder is receiving a static key share as part of this message. This token adds one state transformation to readMessage_a: decryptAndHash is called on the static public key. If any prior Diffie-Hellman shared secret was established between the sender and the recipient, this allows the initiator to communicate their long-term identity with some degree of confidentiality.

• ss: Signals that the responder is calculating a Diffie-Hellman shared secret derived from the initiator’s static key and the responder’s static key as part of this message. This token adds one state transformation to readMessage_a: mixKey, which calls HKDF function using, as input, the existing SymmetricState key and DH(s,rs), the Diffie-Hellman share calculated from the initiator’s static key and the responder’s static key.

Message A’s payload invokes the following operation: decryptAndHash, which performs AEAD decryption on the payload, with the session hash as the associated data (decryptWithAd) and mixHash, which hashes the encrypted payload into the next session hash.

3.4 Other Specification Features

The Noise Protocol Framework specification defines 15 “fundamental patterns”, 23 “deferred patterns” and 21 “PSK patterns”. IK (Fig. 1) and IN (Fig. 2) are two fundamental patterns. Deferred patterns are essentially modi- fied fundamental patterns where the communication of public keys or the occurence of Diffie-Hellman operations is intentionally delayed. PSK pattterns are patterns in which a pre-shared key token appears. Fig. 6 illustrates a deferred pattern based on the fundamental pattern shown in Fig. 1.

The full Noise Protocol Framework specification extends somewhat beyond the description given as part of this work, including features such as “identity hiding” and “dummy keys.” Some of these features are potentially valuable and slated as future work.

70 Deliverable D4.3 NEXTLEAP Grant No. 688722

4 Modeling Noise Security Goals in the Symbolic Model

Since our goal is to evaluate the security guarantees achieved by arbitrary Noise Handshake Patterns, it is crucial to have a set of well-defined security goals on which to base our analysis. We want to formulate these “security grades” in ProVerif as event-based queries. This implies specifying a number of events triggered at specific points in the protocol flow as well as queries predicated on these events.

A set of the queries for the security goals described in this section is generated for each handshake and transport message within a Noise Handshake Pattern, allowing for verification to occur in the comprehensive context described in §2.

The Noise Protocol Framework specification defines different Noise Handshake Patterns to suit different sce- narios. These patterns come with different security properties depending on which keys and shared secrets are employed and when. Two types of security grades are defined: “authentication” grades dealing with the authentication of a message to a particular sender (and optionally, receiver) and “confidentiality” grades dealing with a message’s ability to resist the obtention of plaintext by an unauthorized party.

For example, the Noise Handshake Pattern illustrated in Fig. 1 is described in the original specification as claiming to reach strong security goals: handshake and transport message are attributed authentication grades of 1, 2, 2 and 2 respectively, and confidentiality grades of 2, 4, 5 and 5. Other Noise Handshake Patterns, such as the one described in Fig. 2, sacrifice security properties to deal away with the need to share public keys beforehand or to conduct additional key derivation steps (authentication: 0, 0, 2, 0 and confidentiality: 0, 3, 1 5.) We describe each of these authentication and confidentiality grades in fuller detail below.

In our analysis, we leave the confidentiality grades intact. However, we introduce two new additional security grades, 3 and 4, which provide more nuance for the existing authentication grades 1 and 2. In our analysis, authentication grades 1 and 2 hold even if the authentication of the message can be forged towards the recipient if the sender carries out a separate session with a separate, compromised recipient. Authentication grades 3 and 4 do not hold in this case. This nuance does not exist in the authentication grades defined in the latest Noise Protocol Framework specification.

In all examples below, Bob is the sender and Alice is the recipient. The message in question is message D, i.e. the fourth message pattern within the Noise Handshake Pattern. In the event of a non-existent static key for either Alice or Bob, or of a non-existent PSK, the relevant LeakS or LeakPsk event is removed from the query. A principal c refers to any arbitrary principal on the network, which includes compromised principal Charlie.

4.1 Events

The following events appear in generated ProVerif models:

• SendMsg(principal, principal, stage, bitstring) takes in the identifier of the mes- sage sender, the identifier of the recipient, a “stage” value and the plaintext of the message payload. The “stage” value is the output of a function parametrized by the session ID, a unique value generated for each execution of the protocol using ProVerif’s new keyword, and an identifier of which message this is within the Noise Handshake Pattern (first message, second message, etc.)

• RecvMsg(principal, principal, stage, bitstring) is a mirror event of the above, with the first principal referring to the recipient and the second referring to the sender.

• LeakS(phasen, principal) indicates the leakage of the long-term secret key of the principal. phasen refers to which “phase” the leak occured: in generated ProVerif models, phase 0 encompasses protocol executions that occur while the session is under way, while phase 1 is strictly limited to events that occur after the session has completed and has been closed.

71 Deliverable D4.3 NEXTLEAP Grant No. 688722

• LeakPsk(phasen, principal, principal) indicates the leakage of the pre-shared key (PSK) of the session between an initiator (specified as the first principal) and a responder in the specified phase.

4.2 Authentication Grades

Grade 0 indicates no authentication: the payload may have been sent by any party, including an active attacker.

4.2.1 Sender authentication

In this query, we test for sender authentication and message integrity. If Alice receives a valid message from Bob, then Bob must have sent that message to someone, or Bob had their static key compromised before the session began, or Alice had their static key compromised before the session began:

RecvMsg(alice,bob,stage(d,sid),m) −→ SendMsg(bob,c,stage(d,sid),m) ∨ (LeakS(phase ,bob) LeakPsk(phase ,alice,bob)) 0 ∧ 0 ∨ (LeakS(phase ,alice) LeakPsk(phase ,alice,bob)) 0 ∧ 0

4.2.2 Sender authentication and key compromise impersonation resistance

In this query, we test for sender authentication and Key Compromise Impersonation resistance. If Alice receives a valid message from Bob, then Bob must have sent that message to someone, or Bob had their static key compromised before the session began.

RecvMsg(alice,bob,stage(d,sid),m) −→ SendMsg(bob,c,stage(d,sid),m) ∨ LeakS(phase0,bob)

4.2.3 Sender and received authentication and message integrity

If Alice receives a valid message from Bob, then Bob must have sent that message to Alice specifically, or Bob had their static key compromised before the session began, or Alice had their static key compromised before the session began. This query is not present in the original Noise Protocol Framework specification and is contributed by this work.

RecvMsg(alice,bob,stage(d,sid),m) −→ SendMsg(bob,alice,stage(d,sid),m) ∨ (LeakS(phase ,bob) LeakPsk(phase ,alice,bob)) 0 ∧ 0 ∨ (LeakS(phase ,alice) LeakPsk(phase ,alice,bob)) 0 ∧ 0

4.2.4 Sender and receiver authentication and key compromise impersonation resistance

If Alice receives a valid message from Bob, then Bob must have sent that message to Alice specifically, or Bob had their static key compromised before the session began. This query is not present in the original Noise

72 Deliverable D4.3 NEXTLEAP Grant No. 688722

Protocol Framework specification and is contributed by this work.

RecvMsg(alice,bob,stage(d,sid),m) −→ SendMsg(bob,alice,stage(d,sid),m) ∨ LeakS(phase0,bob)

4.3 Confidentiality Grades

Grade 0 indicates no confidentiality: the payload is sent in cleartext.

4.3.1 Encryption to an ephemeral recipient

In these queries, we test for message secrecy by checking if a passive attacker or active attacker is able to retrieve the payload plaintext only by compromising Alice’s static key either before or after the protocol session. Passing this query under a passive attacker achieves confidentiality grade 1, while doing so under an active at- tacker achieves confidentiality grade 2 (encryption to a known recipient, forward secrecy for sender compromise only, vulnerable to replay.)

attacker (msg (bob,alice,sid)) p1 d −→ (LeakS(phase ,alice) LeakS(phase ,alice)) 0 ∨ 1 ∧ (LeakPsk(phase ,alice,bob) 0 ∨ LeakPsk(phase1,alice,bob))

In the above, attackerp1 indicates that the attacker obtains the message in phase 1 of the protocol execution.

4.3.2 Encryption to a known recipient, weak forward secrecy

In this query, we test for forward secrecy by checking if a passive attacker is able to retrieve the payload plaintext only by compromising Alice’s static key before the protocol session, or after the protocol session along with Bob’s static public key (at any time.) Passing this query under a passive attacker achieves confidentiality grade 3, while doing so under an active attacker achieves confidentiality grade 4 (encryption to a known recipient, weak forward secrecy only if the sender’s private key has been compromised.)

attacker (msg (bob,alice,sid)) p1 d −→ (LeakS(phase ,alice) LeakPsk(phase ,alice,bob)) 0 ∧ 0 ∨ (LeakS(p ,alice) LeakPsk(p ,alice,bob) x ∧ y ∧ LeakS(pz,bob))

In the above, px, py, pz refer to any arbitrary phases.

4.3.3 Encryption to a known recipient, strong forward secrecy

In this query, we test for strong forward secrecy by checking if an active attacker is able to retrieve the pay- load plaintext only by compromising Alice’s static key before the protocol session. Passing this query achieves confidentiality grade 5.

attacker (msg (bob,alice,sid)) p1 d −→ (LeakS(phase ,alice) LeakPsk(phase ,alice,bob)) 0 ∧ 0 73 Deliverable D4.3 NEXTLEAP Grant No. 688722

Pattern Auth. Conf. Pattern Auth. Conf. Pattern Auth. Conf. N 0 2 X1N 0 0 0 0 2 0 1 1 3 1 I1K1 0 4 4 4 4 0 1 5 5 5 K 1 2 X1K 0 2 0 4 4 4 2 1 5 3 5 5 I1X 0 4 4 4 4 0 1 5 5 5 X 1 2 XK1 0 2 4 4 4 0 1 5 5 5 IX1 0 0 4 4 4 0 3 3 5 5 NN 0 0 0 0 1 1 X1K1 0 2 0 4 4 4 0 1 5 3 5 5 I1X1 0 0 4 4 4 0 1 3 5 5 NK 0 2 0 2 1 5 X1X 0 2 0 2 2 2 0 1 5 3 5 5 Npsk0 1 2 NX 0 2 0 0 1 5 XX1 0 0 4 4 4 0 1 3 5 5 Kpsk0 1 2 XN 0 0 2 0 0 1 1 5 X1X1 0 0 0 4 4 4 0 1 3 3 5 5 Xpsk1 1 2 XK 0 2 4 4 4 2 1 5 5 5 K1N 0 0 2 0 0 1 1 5 NNpsk0 1 1 1 1 2 3 3 3 XX 0 2 4 4 4 0 1 5 5 5 K1K 0 4 4 4 4 2 1 5 5 5 NNpsk2 0 1 1 1 0 3 3 3 KN 0 0 2 0 0 3 1 5 KK1 0 4 4 4 0 3 5 5 NKpsk0 1 4 1 4 2 5 3 5 KK 1 4 4 4 2 4 5 5 K1K1 0 4 4 4 0 1 5 5 5 NKpsk2 0 4 1 4 0 3 3 5 KX 0 4 4 4 0 3 5 5 K1X 0 4 4 4 4 0 1 5 5 5 NXpsk2 0 4 1 4 0 3 3 5 IN 0 0 2 0 0 3 1 5 KX1 0 0 4 4 4 0 3 3 5 5 XNpsk3 0 0 4 1 4 0 1 3 3 5 IK 1 4 4 4 2 4 5 5 K1X1 0 0 4 4 4 0 1 3 5 5 XKpsk3 0 0 4 4 4 0 1 3 5 5 IX 0 4 4 4 0 3 5 5 I1N 0 0 2 0 2 0 1 1 5 1 KNpsk0 1 1 4 1 2 3 5 3 NK1 0 2 0 0 1 5 I1K 0 4 4 4 4 2 1 5 5 5 KNpsk2 0 1 4 1 0 3 5 3 NX1 0 0 0 2 0 0 1 3 1 5 IK1 0 4 4 4 0 3 5 5 INpsk1 1 1 4 1 2 3 5 3

Figure 7: Verification results for 50 Noise Handshake Patterns. The numbers in the Authentication and Confidentiality column represent the obtained score for each message, starting from the first message in the Handshake Pattern concerned.

4.4 Limitations on Modeling Security Grades

Our analysis of authentication grades comes with an important limitation: When Noise Explorer generates the authentication queries below, it uses two different values, sida and sidb, to refer to the session ID as registered in the trigger events by Alice and Bob. This differs from, and is in fact less accurate than the queries described previously, which use the same session ID, sid, for both Alice and Bob. We are forced to adopt this approach due to performance limitations in our models during verification should we choose to use a single sid value for both Alice and Bob. However, we argue that since processes with differing sid values cause decryption operations that use shared secrets derived from ephemeral keys to fail, and therefore for those processes to halt, we still obtain essentially the same verification scenarios that these queries target.

Additionally, with regards to our confidentiality grades, whenever a pattern contains a PSK and LeakPSK events start to get involved, we ideally account for cases where one long-term secret is compromised but not the other. This indicates that we may need a richer notion of authenticity and confidentiality grades than the 1-5 markers that the Noise specification provides. For consistency, we are still using the old grades, but to truly understand and differentiate the security provided in many cases, we recommend that the user view the detailed queries and results as generated by Noise Explorer and available in its detailed rendering of the verification results.

5 Verifying Arbitrary Noise Handshake Patterns with Noise Explorer

A central motivation to this work is the obtention of a general framework for designing, reasoning about, formally verifying, implementing and comparing any arbitrary Noise Handshake Pattern. Noise Explorer is a web frame- work that implements all of the formalisms and ProVerif translation logic described so far in this work in order to provide these features.

Noise Explorer is ready for use by the general public today at https://noiseexplorer.com. Here are Noise Explorer’s main functionalities:

74 Deliverable D4.3 NEXTLEAP Grant No. 688722

Designing and validating Noise Handshake Patterns. This allows protocol designers to immediately obtain validity checks that verify if the protocol conforms to the latest Noise Protocol Framework specification.6

Generating cryptographic models for formal verification using automated verification tools. Noise Ex- plorer can compile any Noise Handshake Pattern to a full representation in the applied pi-calculus including cryptographic primitives, state machine transitions, message passing and a top-level process illustrating live protocol execution. Using ProVerif, we can then test against sophisticated security queries starting at basic confidentiality and authentication and extending towards forward secrecy and resistance to key compromise impersonation.

Exploring the first compendium of formal verification results for Noise Handshake Patterns. Since formal verification for complex Noise Handshake Patterns can take time and require fast CPU hardware, Noise Explorer comes with a compendium detailing the full results of almost all Noise Handshake Patterns described in the latest revision of the original Noise Protocol Framework specification. These results are presented with a security model that is more comprehensive than the original specification, as described in §4.

5.1 Accessible High Assurance Verification for Noise-Based Protocols

Noise Explorer users are free to specify any arbitrary Noise Handshake Pattern of their own design. Once this input is validated, formal verification models are generated. The ProVerif verification output can then be fed right back into Noise Explorer, which will then generate detailed interactive pages describing the analysis results.

The initial view of the results includes a pedagogical plain-English paragraph for each message summarizing its achieved security goals. For example, the following paragraph is generated for message D (i.e. the fourth message pattern) of IK:

“Message D, sent by the responder, benefits from sender and receiver authentication and is resistant to Key Compromise Impersonation. Assuming the corresponding private keys are secure, this authentication cannot be forged. Message contents benefit from message secrecy and strong forward secrecy: if the ephemeral private keys are secure and the initiator is not being actively impersonated by an active attacker, message contents cannot be decrypted by an adversary.”

Furthermore, each message comes with a detailed analysis view that allows the user to immediately access a dynamically generated representation of the state transition functions for this particular message as modeled in ProVerif and a more detailed individual writeup of which security goals are met and why. We believe that this “pedagogy-in-depth” that is provided by the Noise Explorer will allow for useful, push-button analysis of any constructed protocol within the Noise Protocol Framework that is comprehensive.

Noise Explorer’s development was done in tandem with discussions with the Noise Protocol Framework author: pre-release versions were built around revision 33 of the Noise Protocol Framework and an update to support re- vision 34 of the framework was released in tandem with the specification revision draft. Revision 34 also included security grade results for deferred patterns that were obtained directly via Noise Explorer’s compendium of for- mal analysis results. We plan to continue collaborating with the Noise Protocol Framework author indefinitely to support future revisions of the Noise Protocol Framework.

5.2 Noise Explorer Verification Results

Noise Explorer was used to generate ProVerif models for more than 50 Noise Handshake Patterns, all of which were subsequently verified with the results shown in Fig. 7. We found that all of the Noise Handshake Patterns evaluated met the security goals postulated in the original Noise Protocol Framework Specification. Verification

6As of writing, Revision 34 is the latest draft of the Noise Protocol Framework. Noise Explorer is continuously updated in collaboration with the authors of the Noise Protocol Framework specification.

75 Deliverable D4.3 NEXTLEAP Grant No. 688722 times varied between less than 30 minutes for simpler (and less secure) patterns (such as NN) to more than 24 hours for some of the more ambitious patterns, such as IK. All of the results are accessible publicly using Noise Explorer’s compendium interface7 and the official Noise Protocol Framework specification has updated in order to take our results into account.

6 Modeling for Forgery Attacks using Noise Explorer

Using ProVerif, we were able to test for the necessity of certain Noise Handshake Patterns and to document a forgery attack within certain Noise Handshake Patterns that becomes possible when these rules are not fol- lowed appropriately. Essentially, we can compose well-known attack vectors (invalid Diffie-Hellman key shares, repeated AEAD nonces) to attack patterns that rely only on static-static key derivation (ss) for authentication.

Consider the pattern KXS below:

KXS : s → ... e → e,ee,s,ss ←

This is a variation of the Noise Handshake Pattern KX that uses ss instead of se, and es, so it is a little more efficient while satisfying the same confidentiality and authentication goals. In particular, the responder can start sending messages immediately after the second message.

However, there is an attack if the responder does not validate ephemeral public values. Suppose a malicious initiator were to send an invalid ephemeral public key e, say e = 0. Then, because of how Diffie-Hellman operations work on X25519, the responder would compute ee = 0 and the resulting key would depend only on the static key ss. Note that while the responder could detect and reject the invalid public key, the Noise specification explicitly discourages this behavior.

Since the responder will encrypt messages with a key determined only by ss (with a nonce set to 0), the malicious initiator can cause it to encrypt two messages with the same key and nonce, which allows for forgery attacks. A concrete man-in-the-middle attack on this pattern is as follows:8

In the pre-message phase, A sends a public static key share sA to B. In the first session: 1. A malicious C initiates a session with B where he pretends to be A. C sends e = Z such that Zx would evaluate to Z for any x. This effectively allows us to model for forcing an X25519 zero-value key share in the symbolic model.

2. B receives e = Z and accepts a new session with:

• hB0 = H(pattern_name)

• ckB1 = hB0

• hB1 = H(hB0,sA,e = Z)

3. B generates re1, computes ee = Z and sends back (re1,ee = Z,sB,ssAB,msga) where sB is encrypted with ckB2 = H(ckB1,ee = Z) as the key, 0 as the nonce and hB2 = H(hB1,re1,ee = Z) as associated data.

7https://noiseexplorer.com/patterns/ 8For simplicity, here we use H to represent the more complex key derivation and mixing functions.

76 Deliverable D4.3 NEXTLEAP Grant No. 688722

4. msga is encrypted with ckB3 = H(ckB2,ssAB) as the key, 0 as the nonce and hB3 = H(hB2,sB) as associated data.

5. C discards this session but remembers the encrypted message.

In a second session:

1. A initiates a session with B by sending e. So, at A:

• hA0 = H(pattern_name)

• ckA1 = hA0

• hA1 = H(hA0,sA,e) 2. C intercepts this message and replaces it with the invalid public key Z = 0.

3. B receives e = Z and accepts a new session with:

• hB0 = H(pattern_name)

• ckB1 = hB0

• hB1 = H(hB0,sA,e = Z)

4. B generates re2, computes ee = Z and sends back (re2,ee = Z,sB,ssAB,msgb) where sB is encrypted with ckB2 = H(ckB1,ee = Z) as the key, 0 as the nonce and hB2 = H(hB1,re) as associated data.

5. msgb is encrypted with ckB3 = H(ckB2,ssAB) as the key, 0 as the nonce and hB3 = H(hB2,sB) as associated data.

6. C intercepts this response.

Notably, the encryption keys (ckB3) and the nonces (0) used for msga in session 1 and msgb in session 2 are the same. Hence, if the underlying AEAD scheme is vulnerable to the repeated nonces attack, C can compute the AEAD authentication key for ckB3 and tamper with msga and msgb to produce a new message msgc that is validly encrypted under this key. Importantly, C can also tamper with the associated data hB3 to make it match any other hash value.

C replaces the message with (re = Z,ee = Z,sB,ssAB,msgc) and sends it to A, where sB is re-encrypted by C using ckB2 which it knows and msgc is forged by C using the AEAD authentication key for ckB3. A receives the message (re = Z,ee = Z,sB,ssAB,msgc) and computes ckA2 = H(ckA1,ee = Z) and hA2 = H(hA1,ee = Z). A then decrypts sB. A then computes ckA3 = H(ckA2,ssAB) and hA3 = H(hA2,sAB) and decrypts msgc. This decryption succeeds since ckA3 = ckB3. The attacker C therefore has successfully forged the message and the associated data.

At a high level, the above analysis can be read as indicating one of three shortcomings:

1. Using ss in Noise Handshake Patterns must be done carefully. A Noise Handshake Pattern validation rule could be introduced to disallow the usage of ss in a handshake unless it is accompanied by se or es in the same handshake pattern.

2. Diffie-Hellman key shares must be validated. Implementations must validate incoming Diffie-Hellman public values to check that they are not one of the twelve known integers [19] which can cause a scalar multiplication on the X25519 curve to produce an output of 0.

3. Independent sessions must be checked for AEAD key reuse. Ephemeral and static public key values are mixed into the encryption key derivation step.

As a result of this analysis, revision 34 of the Noise Protocol Framework specification included clearer wording of the validity rule which would render the KXS pattern invalid:

77 Deliverable D4.3 NEXTLEAP Grant No. 688722

After calculating a Diffie-Hellman shared secret between a remote public key (either static or ephemeral) and the local static key, the local party must not perform any encryptions unless it has also calculated a Diffie-Hellman key share between its local ephemeral key and the remote public key. In particular, this means that:

• After an se or ss token, the initiator must not send a payload unless there has also been an ee or es token respectively.

• After an es or ss token, the responder must not send a payload unless there has also been an ee or se token respectively.

7 Automatic Generation of Software Implementations

Noise Explorer can also automatically generate software implementations for arbitrary Noise Handshake Pat- terns. We target Go as our first language for code generation given that it is engineered for usage in concurrent server systems where secure channel protocols are frequently required, and its adoption by Google, CloudFlare, Facebook and others.

Noise Explorer’s ability to generate software implementations complements its ability to assist with designing and formally verifying Noise Handshake Patterns: immediately after the pattern is designed and its security guarantees are ascertained, it can be prototyped in production systems with a software implementation that is safe to use.

Like its ProVerif model output, Noise Explorer’s generated implementations are fully human-readable. If a gen- erated implementation is part of the original implementations described in the Noise Protocol Framework spec- ification, then it is also possible to automatically test it against test vectors obtained from Cacophony [20], a Haskell implementation of the Noise Protocol Framework. Generated implementations have also been tested for side channel resistance, memory efficiency and performance.

One major benefit of the Noise Protocol Framework is that it allows for the design and implementation of use case-specific secure channel protocols. For example, WireGuard implements the IKpsk2 Noise Handshake Pattern while WhatsApp chooses to implement XX and IK in different parts of the application. This leads to generated implementations being able to do away with much of the state machine complexity that has plagued TLS, often resulting serious vulnerabilities [21].

In Figure 8, we show a cursory comparison between BearSSL [22], Go’s standard TLS implementation as well as two Noise Handshake Patterns generated from Noise Explorer. In all four test cases, care was taken to make the comparison as fair as possible by only including protocol element types that figure across all of the implementations. A strong difference in code complexity is apparent.

8 Conclusion and Future Work

In this work, we have provided the first formal treatment of the Noise Protocol Framework. We translate our formalisms into the applied pi-calculus and use this as the basis for automatically generating models for the automated formal verification of arbitrary Noise Handshake Patterns. We coalesce our results into Noise Ex- plorer, an online framework for pedagogically designing, validating, verifying, reasoning about and implementing arbitrary Noise Handshake Patterns.

Noise Explorer has already had an impact as the first automated formal analysis targeting any and all Noise Handshake Patterns. Verification results obtained from Noise Explorer were integrated into the original specifi- cation and refinements were made to the validation rules and security goals as a result of the scrutiny inherent to our analysis.

78 Deliverable D4.3 NEXTLEAP Grant No. 688722

15,000 13,434

10,000

5,541

Lines of5 Code ,000

341 301 0 BearSSL GoTLS IKpsk2 N Figure 8: Implementation sizes for BearSSL, Go’s standard TLS library and two Go Noise Handshake Pattern implementations generated by Noise Explorer. Due to the modular nature of TLS, the BearSSL and GoTLS figures are best-effort approximations.

Ultimately, it is not up to us to comment on whether the Noise Protocol Framework presents a “good” framework, per se. However, we present confident results that its approach to protocol design allows us to cross a new bridge for not only designing and implementing more robust custom secure channel protocols, but also applying existing automated verification methodologies in new and more ambitious ways.

For the formal verification aspect, future work could include the automated generation of computational models to be verified using CryptoVerif and of verified implementations of Noise Handshake Patterns. The scope of our formalisms could also be extended to include elements of the Noise Protocol Framework specification, such as queries to test for identity hiding.

For Noise Explorer’s software implementation features, future work is currently slated to go beyond software implementations being generated in Golang and towards supporting the automatic generation of WebAssem- bly [23], Rust [24] and F* [25] implementations of arbitrary Noise Handshake Patterns.

Acknowledgements

We would like to thank Bruno Blanchet for his insight with regards to modeling and optimization in ProVerif and for his valuable feedback on earlier drafts of this paper. We also present our thanks to Thomas Pornin for his insightful feedback on BearSSL implementation size estimation. This project has received funding from the European Union’s Horizon 2020 NEXTLEAP Project (grant agreement n. 688722).

References

[1] Karthikeyan Bhargavan, Antoine Delignat-Lavaud, Cédric Fournet, Alfredo Pironti, and Pierre-Yves Strub. Triple handshakes and cookie cutters: Breaking and fixing authentication over TLS. In IEEE Symposium on Security & Privacy (Oakland), pages 98–113, 2014.

[2] Gavin Lowe. An attack on the needham- schroeder public- key authentication protocol. Information pro- cessing letters, 56(3), 1995.

[3] Roger M Needham and Michael D Schroeder. Using encryption for authentication in large networks of computers. Communications of the ACM, 21(12):993–999, 1978.

79 Deliverable D4.3 NEXTLEAP Grant No. 688722

[4] Karthikeyan Bhargavan, Antoine Delignat-Lavaud, and Alfredo Pironti. Verified contributive channel bind- ings for compound authentication. In Network and Distributed System Security Symposium (NDSS ’15), 2015.

[5] Cas Cremers, Marko Horvat, Jonathan Hoyland, Sam Scott, and Thyla van der Merwe. A comprehensive symbolic analysis of TLS 1.3. In Proceedings of the 2017 ACM SIGSAC Conference on Computer and Communications Security, CCS ’17, pages 1773–1788, New York, NY, USA, 2017. ACM.

[6] David Adrian, Karthikeyan Bhargavan, Zakir Durumeric, Pierrick Gaudry, Matthew Green, J Alex Halder- man, Nadia Heninger, Drew Springall, Emmanuel Thomé, Luke Valenta, et al. Imperfect forward secrecy: How Diffie-Hellman fails in practice. In ACM SIGSAC Conference on Computer and Communications Se- curity (CCS), pages 5–17, 2015.

[7] Trevor Perrin. The Noise protocol framework, 2015. Available at http://www.noiseprotocol.org.

[8] Vincent Cheval and Bruno Blanchet. Proving more observational equivalences with ProVerif. In Interna- tional Conference on Principles of Security and Trust, pages 226–246. Springer, 2013.

[9] Bruno Blanchet. Modeling and verifying security protocols with the applied pi calculus and ProVerif. Foun- dations and Trends in Privacy and Security, 1(1–2):1–135, October 2016.

[10] Martín Abadi, Bruno Blanchet, and Cédric Fournet. The applied pi calculus: Mobile values, new names, and secure communication. J. ACM, 65(1):1:1–1:41, 2018.

[11] Jason A Donenfeld. WireGuard: next generation kernel network tunnel. In 24th Annual Network and Distributed System Security Symposium, NDSS, 2017.

[12] Benjamin Lipp. A Mechanised Computational Analysis of the WireGuard Virtual Private Network Protocol. https://benjaminlipp.de/master-thesis.

[13] Jason Donenfeld and Kevin Milner. Formal verification of the WireGuard protocol, 2017. https://www.wireguard.com/formal-verification/.

[14] Benjamin Dowling and Kenneth G. Paterson. A cryptographic analysis of the WireGuard protocol. Cryptol- ogy ePrint Archive, Report 2018/080, 2018. https://eprint.iacr.org/2018/080.

[15] Karthikeyan Bhargavan Nadim Kobeissi and Bruno Blanchet. Automated verification for secure messaging protocols and their implementations: A symbolic and computational approach. In IEEE European Sympo- sium on Security and Privacy (EuroS&P), 2017.

[16] Karthikeyan Bhargavan, Bruno Blanchet, and Nadim Kobeissi. Verified models and reference implementa- tions for the TLS 1.3 standard candidate. In Security and Privacy (SP), 2017 IEEE Symposium on, pages 483–502. IEEE, 2017.

[17] Phillip Rogaway. Authenticated-encryption with associated-data. In Ninth ACM Conference on Computer and Communications Security (CCS-9), pages 98–107, Washington, DC, November 2002. ACM Press.

[18] Hugo Krawczyk. Cryptographic extraction and key derivation: The HKDF scheme. In Advances in Cryptol- ogy (CRYPTO), pages 631–648. 2010.

[19] Daniel J. Bernstein. Curve25519: New Diffie-Hellman speed records. In Public Key Cryptography (PKC), pages 207–228, 2006.

[20] John Galt. cacophony: A library implementing the noise protocol, 2019. http://hackage.haskell.org/ package/cacophony.

[21] B. Beurdouche, K. Bhargavan, A. Delignat-Lavaud, C. Fournet, M. Kohlweiss, A. Pironti, P-Y Strub, and J-K Zinzindohoué. A messy state of the union: Taming the composite state machines of TLS. In IEEE S&P (Oakland), 2015.

[22] Thomas Pornin. Bearssl: a smaller ssl/tls library, 2019. https://bearssl.org/. 80 Deliverable D4.3 NEXTLEAP Grant No. 688722

ProVerif M ::= terms v values a names f (M1,...,Mn) function application E ::= enriched terms M return value new a : τ;E new name a of type τ let x = M in E variable definition if M = N then E1 else E2 if-then-else P,Q ::= processes 0 null process in(M,x : τ);P input x from channel M out(M,N);P output N on channel M let x = M in P variable definition P Q parallel composition | !P replication of P insert a(M1,...,Mn);P insert into table a get a(=M1,x2,...,xn) in P get table entry specified by M1 event M;P event M phase n;P enter phase n ∆ ::= declaration type τ type τ free a : τ name a query q query q table a(τ1,...,τn) table a fun C(τ1,...,τn) : τ constructor reduc forall x1 : τ1,...,xn : τn; f (M1,...,Mn) = M destructor equation forall x1 : τ1,...,xn : τn;M = M0 equation letfun f (x1 : τ1,...,xn : τn) = E pure function let p(x1 : τ1,...,xn : τn) = P process Σ ::= ∆1....∆n.process P script

Figure 9: ProVerif syntax, based on the applied-pi calculus.

[23] WebAssembly Core Specification, 2018. https://webassembly.github.io/spec/core/bikeshed/ index.html.

[24] Nicholas D Matsakis and Felix S Klock II. The rust language. In ACM SIGAda Ada Letters, volume 34, pages 103–104. ACM, 2014.

[25] Jonathan Protzenko, Jean-Karim Zinzindohoué, Aseem Rastogi, Tahina Ramananandro, Peng Wang, San- tiago Zanella-Béguelin, Antoine Delignat-Lavaud, Cat˘ alin˘ Hri¸tcu,Karthikeyan Bhargavan, Cédric Fournet, et al. Verified low-level programming embedded in F. Proceedings of the ACM on Programming Languages, 1(ICFP):17, 2017.

81 Deliverable D4.3 NEXTLEAP Grant No. 688722

1 let initiator(me:principal, them:principal, sid: 1 let responder(me:principal, them:principal, sid: sessionid) = sessionid) = 2 let s= keypairpack(bit2key(empty), bit2key(empty)) in 2 let s= generate_keypair(key_s(me)) in 3 out(pub, getpublickey(s)); 3 out(pub, getpublickey(s)); 4 ((let e= keypairpack(bit2key(empty), bit2key(empty)) 4 ((let e= keypairpack(bit2key(empty), bit2key(empty)) in in 5 let rs= getpublickey(generate_keypair(key_s( 5 let rs= bit2key(empty) in them))) in 6 let re= bit2key(empty) in 6 let re= bit2key(empty) in 7 let hs:handshakestate= initialize_responder( 7 let hs:handshakestate= initialize_initiator( empty,s,e, rs, re, bit2key(empty)) in empty,s,e, rs, re, bit2key(empty)) in 8 insert statestore(me, them, sid, statepack_a(hs) 8 insert statestore(me, them, sid, statepack_a(hs) ) ) 9 ) | (get statestore(=me, =them, =sid, statepack_a(hs)) 9 ) | (get statestore(=me, =them, =sid, statepack_a(hs)) in in 10 in(pub, message_a:bitstring); 10 let (hs:handshakestate, message_a:bitstring) = 11 let (hs:handshakestate, plaintext_a:bitstring, writeMessage_a(me, them, hs, msg_a(me, them, valid:bool) = readMessage_a(me, them, hs, sid), sid) in message_a, sid) in 11 event SendMsg(me, them, stagepack_a(sid), msg_a( 12 event RecvMsg(me, them, stagepack_a(sid), me, them, sid)); plaintext_a); 12 insert statestore(me, them, sid, statepack_b(hs) 13 insert statestore(me, them, sid, statepack_b(hs) ); ); 13 out(pub, message_a) 14 0 14 ) | (get statestore(=me, =them, =sid, statepack_b(hs)) 15 ) | (get statestore(=me, =them, =sid, statepack_b(hs)) in in 15 in(pub, message_b:bitstring); 16 let (hs:handshakestate, message_b:bitstring, cs1 16 let (hs:handshakestate, plaintext_b:bitstring, :cipherstate, cs2:cipherstate) = valid:bool, cs1:cipherstate, cs2:cipherstate writeMessage_b(me, them, hs, msg_b(me, them, ) = readMessage_b(me, them, hs, message_b, sid), sid) in sid) in 17 event SendMsg(me, them, stagepack_b(sid), msg_b( 17 event RecvMsg(me, them, stagepack_b(sid), me, them, sid)); plaintext_b); 18 insert statestore(me, them, sid, statepack_c(hs, 18 insert statestore(me, them, sid, statepack_c(hs, cs1, cs2)); cs1, cs2)); 19 out(pub, message_b) 19 0 20 ) | !(get statestore(=me, =them, =sid, statepack_c(hs, 20 ) | !(get statestore(=me, =them, =sid, statepack_c(hs, cs1, cs2)) in cs1, cs2)) in 21 let hs= handshakestatesetcs(hs, cs1) in 21 let hs= handshakestatesetcs(hs, cs1) in 22 in(pub, message_c:bitstring); 22 let (hs:handshakestate, message_c:bitstring) = 23 let (hs:handshakestate, plaintext_c:bitstring, writeMessage_c(me, them, hs, msg_c(me, them, valid:bool) = readMessage_c(me, them, hs, sid), sid) in message_c, sid) in 23 event SendMsg(me, them, stagepack_c(sid), msg_c( 24 event RecvMsg(me, them, stagepack_c(sid), me, them, sid)); plaintext_c); 24 insert statestore(me, them, sid, statepack_d(hs, 25 insert statestore(me, them, sid, statepack_d(hs, handshakestategetcs(hs), cs2)); handshakestategetcs(hs), cs2)); 25 out(pub, message_c) 26 0 26 ) | !(get statestore(=me, =them, =sid, statepack_d(hs, 27 ) | !(get statestore(=me, =them, =sid, statepack_d(hs, cs1, cs2)) in cs1, cs2)) in 27 let hs= handshakestatesetcs(hs, cs2) in 28 let hs= handshakestatesetcs(hs, cs2) in 28 in(pub, message_d:bitstring); 29 let (hs:handshakestate, message_d:bitstring) = 29 let (hs:handshakestate, plaintext_d:bitstring, writeMessage_d(me, them, hs, msg_d(me, them, valid:bool) = readMessage_d(me, them, hs, sid), sid) in message_d, sid) in 30 event SendMsg(me, them, stagepack_d(sid), msg_d( 30 event RecvMsg(me, them, stagepack_d(sid), me, them, sid)); plaintext_d); 31 (* Final message, do not pack state*) 31 (* Final message, do not pack state*) 32 out(pub, message_d) 32 event RecvEnd(valid) 33 ) | (event LeakS(phase0, me); 33 ) | (event LeakS(phase0, me); 34 out(pub, key_s(me)) 34 out(pub, key_s(me)) 35 ) | (phase 1; 35 ) | (phase 1; 36 event LeakS(phase1, me); 36 event LeakS(phase1, me); 37 out(pub, key_s(me)))). 37 out(pub, key_s(me)))).

Figure 10: Initiator and responder processes for the IK Noise Handshake Pattern.

82 D4.2 NEXTLEAP Grant No. 688722

5 Wireguard (VPN)

83 Deliverable D4.3 NEXTLEAP Grant No. 688722

1 Introduction

The traditional distinction between a secure intranet and the untrusted Internet is becoming less relevant as more and more enterprises host internal services on cloud-based servers distributed across multiple data centres. Sensitive data that used to travel only between physically proximate machines within secure buildings is now sent across an unknown number of network links that may be controlled by malicious entities.

To maintain the security of such distributed intranets, the most powerful tools at the disposal of system admin- istrators are Virtual Private Network (VPN) protocols that set up low-level secure channels between machines, and hence can be used to transparently protect all the data exchanged between them. Indeed, all leading cloud providers now offer VPN gateways, so that enterprises can treat cloud-based servers as if they were located within their intranet.1

Standards vs. Custom Protocols. Most popular VPN solutions are based on Internet standards like IPsec [1] and TLS [2], for several reasons. First, these protocols typically have multiple interoperable implementations that are available on all mainstream operating systems, so the VPN software can be easily built as a layer on top. Second, standards are designed to be future-proof by relying on versioning and cryptographic agility, so that a VPN protocol can easily move from one protocol version or cryptographic algorithm to another if (say) a weakness were found on some configuration. Third, published standards typically have been closely scrutinized by a large number of interested parties, and hence are believed to be less likely to contain obvious security flaws.

Conversely, using a standard protocol also has its disadvantages. Standardization takes time, and so a standard protocol may not use the most modern cryptographic algorithms. On the contrary, the need for interoperability and backwards compatibility often force implementations to continue support for obsolete cryptographic algorithms, leading to cryptanalytic attacks [3] and software flaws [4]. Over time, standards and their implementations can grow to an unmanageable size that can no longer be studied as a whole, allowing logical flaws to hide in unused corners of the protocol [5].

Consequently, many new secure channel protocols eschew standardisation in favor of a lean design that uses only modern cryptography and supports minimal cryptographic agility. The succinctness of the protocol description aids auditability, and the lack of optional features reduces complexity. Examples of this approach are the Signal protocol [6] used in many secure messaging systems and the Noise protocol framework [7].

WireGuard is a VPN protocol that adopts this design philosophy [8]. It implements and extends a secure channel protocol derived from the Noise framework, and it chooses a small set of modern cryptographic primitives. By making these choices, WireGuard is able to provide a high-quality VPN in a few thousand lines of code, and is currently being considered for adoption within the Linux kernel. The design of WireGuard is detailed and informally analyzed in [8], but a protocol of such importance deserves a thorough security analysis.

A Need for Mechanised Proofs. Having a succinct, well-documented description is a good basis for understand- ing, auditing, and implementing a custom cryptographic protocol, but in itself is no guarantee that the protocol is secure. Symbolic analysis with tools like ProVerif [9] and Tamarin [10] can help find logical flaws, and WireGuard already has been analysed using Tamarin [11]. However, symbolic analyses do not constitute a full cryptographic proof. For example, they cannot demonstrate the absence of cryptanalytic attacks on secure channels and VPNs (e.g. [3].)

Cryptographic proofs provide the highest form of formal assurance, but writing proofs by hand requires significant expertise and effort, especially if the proof is to account for the precise low-level details of a real-world protocol. And as proofs get larger, the risk of introducing proof errors becomes non-negligible. All this effort is hard to justify for a custom protocol which may change as the software evolves. For example, a manual cryptographic proof for the WireGuard protocol appears in [12], but this proof would need to be carefully reviewed and adapted if the WireGuard protocol were to change in any way or if a variant of WireGuard were to be proposed.

1https://cloud.google.com/vpn/docs/concepts/overview,https://docs.aws.amazon.com/vpc/latest/userguide/ vpn-connections.html,https://azure.microsoft.com/en-us/services/vpn-gateway/

84 Deliverable D4.3 NEXTLEAP Grant No. 688722

We advocate the use of mechanised provers to build cryptographic proofs, so that they can be checked for errors, and can be easily modified to accommodate different variants of the protocol. In this paper, we rely on the CryptoVerif protocol verifier [13, 14] to build a proof of WireGuard. CryptoVerif relies on a computational model of cryptography, and generates machine-checkable proofs by sequences of games, like those manually written by cryptographers.

Uncovering Real-World Cryptographic Assumptions. A mechanised proof also allows the analyst to experi- ment with a variety of cryptographic assumptions and discover the precise set of assumptions that a protocol’s security depends on.

In some cases, a protocol may require an unusual assumption about a hash function, or a stronger assumption about encryption than one may have expected, and these cases can provide a guide to implementers on what concrete crypto algorithms should or should not be used to instantiate the protocol. For example, in our analysis of WireGuard, we find that most of the standard properties require only standard assumptions about the underlying authenticated encryption scheme (AEAD) but identity hiding requires a stronger assumption, which is satisfied by the specific algorithms used by WireGuard, but may not be provided by other AEAD constructions.

In other cases, a protocol’s use of a cryptographic primitive may motivate a new, more precise model of the primitive. Protocols like WireGuard seek to depend on a small set of primitives and reuse them in different ways. For example, WireGuard relies on the Curve25519 elliptic curve Diffie-Hellman operation for an ephemeral key exchange as well as for entity authentication. It uses Curve25519 public keys both as identities and as unique nonces to identify sessions. To verify that Curve25519 is appropriate for all these usages, and to prove the absence of attacks such as replays, identity mis-binding, and key compromise impersonation, we need to account for the details of the Curve25519 group, rather than rely on a generic Diffie-Hellman assumption. Hence, we propose a new model for Curve25519 in CryptoVerif and prove WireGuard secure against this model.

Contributions. We present the first mechanised proof for cryptographic design of the WireGuard VPN, including the Noise IKpsk2 secure channel protocol it uses. In addition to classic key exchange security for IKpsk2, we examine the identity hiding and denial-of-service protections provided by WireGuard. We conclude with a discussion of the strengths and weaknesses of WireGuard, and propose improvements that would allow for stronger security theorems.

Our work also provides contributions reusable beyond the proof of WireGuard. To the best of our knowledge, this is the first mechanised proof for any cryptographic protocol that takes into account the precise structure of the Curve25519 group. We also prove a series of indifferentiability results that allow us to simplify sequences of random oracle calls, and we made several extensions to CryptoVerif that we mention in the rest of the paper when we use them.

The extended version of CryptoVerif, our models of WireGuard, and the long version of this paper are available in the supplemental material provided with this submission.

2 WireGuard

WireGuard [8] establishes a VPN tunnel between two remote hosts in order to securely encapsulate all Internet Protocol (IP) traffic between them. The main design goals of WireGuard are to be simple, fast, modern, and secure. In order to establish a tunnel, a system administrator only needs to configure the IP address and long-term public key for the remote host. With this information, WireGuard can establish a secure channel, using a protocol derived from the Noise framework, instantiated with fast, modern cryptographic primitives like Curve25519 and BLAKE2. The full WireGuard VPN is implemented in a few thousand lines of code that can run on multiple platforms, but for performance, is usually run within the operating system kernel. In particular, WireGuard is in the process of being incorporated into the Linux kernel (most likely Linux 4.2/5.0), as an alternative to IPsec.

In this section, we focus on the cryptographic design of WireGuard. We begin by describing the secure channel

85 Deliverable D4.3 NEXTLEAP Grant No. 688722 component, then the extensions WireGuard makes for denial-of-service and stealthy operation. We end the section by detailing the concrete cryptographic algorithms used by WireGuard and the list of informal security goals it seeks to achieve.

2.1 Secure Channel Protocol: Noise IKpsk2

Noise [7] is a framework for building two-party cryptographic protocols that are secure by construction. Using the building blocks in this framework, a designer can create a new protocol that matches a desired subset of security guarantees: mutual or optional authentication, identity hiding, forward secrecy etc. The Noise specification also includes a list of curated pre-defined protocols, with an informal analysis of their message-by-message security claims. WireGuard instantiates one of these protocols, which is called IKpsk2, and extends it to provide further guarantees needed by VPNs.

The secure channel protocol is depicted in Figure 1a, and the cryptographic computations are detailed in Figure 1b, using notations similar to [8]. Before the protocol begins, the initiator i and the responder r are assumed to have pub pub exchanged their long-term static public keys (Si ,Sr ). Optionally, they may have also established a pre-shared symmetric key (psk); if this key is absent it is set to a key-sized bit string of zeros.

Message Exchange. The protocol begins when i sends the first handshake message to r, which includes the following components:

I : a fresh session identifier, generated by i, • i pub E : a fresh ephemeral public key, generated by i, • i pub S : i’s static public key, encrypted for r, • i ts : a timestamp, encrypted with a key that can be computed only by i and r, and • J K mac1,mac2: message authentication codes (see 2.2). • J K § In response, r sends the second handshake message containing:

I : i’s session identifier, • i I : a fresh session identifier, generated by r, • r pub Er : a fresh ephemeral public key, generated by r, • empty : an empty bytestring encrypted with a key that can be computed only by i and r, and • mac1,mac2: message authentication codes (see 2.2). • J K § The encrypted payloads in the two messages serve as authenticators: by computing the corresponding encryption key, each party proves that it knows the private key for its static public key. The encryption key for the second message also requires knowledge of the optional psk providing an additional authentication guarantee. The two ephemeral keys add fresh session-specific key material that can be used to compute (forward) secret session keys known only to i and r.

At the end of these two messages, i and r derive authenticated encryption keys (T →,T ←) that can be used to transport IP traffic in the two directions. Importantly, i sends the first transport message, hence confirming the successful completion of the handshake to r, before r sends it any encrypted traffic. Each of these transport messages includes:

I or I : the recipient’s session identifier, • i r N or N : the current message counter, • ←j →j P : an IP datagram, encrypted under the traffic key. • j

86 Deliverable D4.3 NEXTLEAP Grant No. 688722

Cryptographic Computations. Figure 1b describes how each of these message components and traffic keys are computed. As the handshake proceeds, i and r compute a series of transcript hashes (H0,H1,...,H7) that hashes in all the public data used in the two handshake messages, including:

prologue,protocol name: strings identifying the protocol, • pub pub E ,Er : both ephemeral public keys, • i pub pub Sr , S : both static public keys, but with initiator’s key in encrypted form, • i ts , empty : both encrypted handshake payloads, and • J K π: an identifier derived from the pre-shared key. • J K J K These transcript hashes serve as unique identifiers for the current stage of session. In particular, no two completed WireGuard sessions should have the same H7.

Both parties also derive a sequence of chaining keys (C0,C1,...,C7) by mixing in all the key material, including: pub pub protocol name, E ,Er , • i priv priv dh(E ,Sr ): the ephemeral-static Diffie-Hellman shared secret computed using the initiator’s ephemeral • i key and the responder’s static key, priv priv dh(S ,Sr ): the static-static shared secret, • i priv priv dh(E ,Er ): the ephemeral-ephemeral shared secret, • i priv priv dh(S ,Er ): the static-ephemeral shared secret, and • i psk: the (optional) pre-shared key. • The protocol uses all four combinations of static and ephemeral Diffie-Hellman shared-secret computations to maximally protect against the compromise of some of these keys. The psk also serves as a defensive countermeasure against quantum adversaries who may be able to break the Diffie-Hellman construction, but not hkdf. Hence, by using a frequently updated psk, WireGuard users can protect current sessions against future quantum adversaries.

Each chaining key is mixed into the next chaining key via an hkdf key derivation that also outputs encryption keys as needed. This chain of key derivations outputs two encryption keys (k1,k2) for the first handshake message, an encryption key (k3) and a PSK identifier (π) for the second message, and traffic keys (T ←,T →) for all subsequent transport messages.

To encrypt each message, WireGuard uses an authenticated encryption scheme with associated data (AEAD) that takes a key, a counter, a plaintext (padded up to the nearest blocksize) and an optional hash value as associated data. The encryptions in the handshake messages use the current transcript hash (H2,H3,H6) as associated data, which guarantees that the two participants have a consistent session transcript. Transport messages use an empty string as associated data. The message counter is initially set to 0 for each AEAD key and incremented by 1 every time the key is reused.

Relationship with IKpsk2. The secure channel protocol described above is a direct instantiation of Noise IKpsk2, with four notable details. First, WireGuard adds local session identifiers (Ii,Ir) for the initiator and responder. Second, WireGuard fixes the payload of the first message to a timestamp, and the second message to be the empty string. Third, WireGuard stipulates that the first traffic message is sent from the initiator to the responder. Fourth, WireGuard excludes zero Diffie-Hellman shared secrets to avoid points of small order, while Noise recommends not to perform this check. We also observe that although this protocol is superficially similar to other popular Noise protocols like IK (which is used in WhatsApp), there are important differences between these variants and a proof for one does not translate to the other.

87 Deliverable D4.3 NEXTLEAP Grant No. 688722

2.2 Extensions for Stealth and Denial-of-Service

A VPN protocol operates at a low-level in the networking stack and hence needs to not only protect against cryptographic attacks, but also real-world network-level attacks such as denial of service (DOS). Indeed, a cryptographic protocol like IKpsk2 that needs to perform two expensive Diffie-Hellman operations before it can even authenticate a handshake message is even more vulnerable to DOS: an attacker can send bogus messages that tie up computing resources on the recipient. A further security goal for WireGuard is that its VPN endpoints should be stealthy, in the sense that it should not be possible for a network attacker to blindly scan for WireGuard services.

To support stealthy operation, WireGuard endpoints do not respond to any handshake message unless the sender can prove that it know the static public key of the recipient. This proof is incorporated in the mac1 field included in each handshake message, which contains a message authentication code (MAC) computed over the prefix of the current handshake message up to but not including mac1, using a MAC key derived from the recipient’s static public key. The recipient verifies this MAC before processing the message, and stays silent if the MAC fails. Hence, a network attacker who does not know the public key cannot detect whether WireGuard is running on a machine.

To protect against DOS, WireGuard incorporates a cookie-based protocol (depicted in Figure 1c) that a host can use when it is under load. For example, if the responder suspects it is under a DOS attack, it can refuse to process the first handshake message and instead send back an initiator-specific fresh cookie (τ) that is computed from a frequently rotated secret key (Rr) (known only to the responder) and the initiator’s IP address (IPi) and source port (Porti). The responder encrypts this cookie for the initiator, using a key derived from the initiator’s static public key, a fresh nonce, and the mac1 field of the first message as associated data. The initiator decrypts τ and then retries the handshake by sending the first message again, but this time with a second field mac2 that contains a MAC over the full message up to and including mac1, using τ as the MAC key. After verifying this MAC, the responder continues with the standard handshake.

However, to obtain τ, an attacker must be able to read messages on the network path between the initiator and responder and must also know the initiator’s static key (which is never sent in the clear by the protocol). And even if the attacker has both these capabilities, it is required to perform session specific cryptographic computations for every handshake message it sends to the responder, significantly limiting its ability to mount a DOS attack. Hence, this cookie protocol protects the recipient from brute-force network attacks.

Note that the mac2 field is included in both handshake messages, and hence can be used in both directions, to protect both the initiator and responder from DOS attacks.

The two MACs are WireGuard-specific mechanisms which are not present in IKpsk2. Since they do not use any of the session keys (or hashes or chaining keys) that are used in IKpsk2, adding these mechanisms should, in principle, not affect the security of the secure channel protocol. However, since the static public keys of the two hosts are used in the two MACs, we need to carefully study their impact on the identity-hiding guarantees of IKpsk2.

2.3 Instantiating the Cryptographic Algorithms

WireGuard uses a small set of cryptographic constructions and instantiates them with modern algorithms, carefully chosen to provide strong security as well as high performance:

dh: all Diffie-Hellman operations use the Curve25519 elliptic curve [15]; • hash: the BLAKE2s hash function [16]; • aenc: authenticated encryption for handshake and traffic message uses the AEAD scheme ChaCha20Poly1305 [17], • using the message counter as nonce;

88 Deliverable D4.3 NEXTLEAP Grant No. 688722

xaenc: cookie encryption uses an extended AEAD construction using XChaCha20Poly1305, which incor- • porates a 192-bit random nonce [18] into the standard ChaCha20Poly1305 construction;

mac: all MAC operations use the keyed MAC variant of the BLAKE2s hash function; • hkdf : all key derivations use the HKDF construction [19], using BLAKE2s as the underlying hash function. • n The values labelmac1 and labelcookie are distinct constants.

2.4 Security Goals, Informally

Using the mechanisms described in this section, WireGuard seeks to provide the following set of strong security guarantees, combining the security claims of Noise IKpsk2 with the additional DOS and stealth goals of WireGuard. In the following, we use honest to refer to a host whose static private key is unknown to the adversary; and compromised to refer to hosts whose keys have been leaked:

Correctness: If an honest initiator and an honest responder complete a WireGuard handshake and the • messages are not altered by an adversary, then the transport data keys (T →,T ←) and the transcript hash H7 are the same on both hosts. Secrecy: If a transport data message P is sent over a tunnel between two honest hosts, then this message • is kept confidential from the adversary. Furthermore, the traffic keys for this tunnel are also confidential. priv priv Forward Secrecy: Secrecy for a session holds even if both the static private keys (S , Sr ) and the • i pre-shared key (psk) become known to the adversary, but only after the session has been completed and all its traffic keys and chaining keys are deleted by both parties.

Secrecy also holds even if the static and ephemeral keys are compromised (e.g. by a quantum adversary), as long as the pre-shared key is not compromised.

Mutual Authentication: If an honest initiator (resp. responder) completed a handshake (ostensibly) with • an honest peer, then that peer must have participated in this handshake. Moreover, if a host A receives a plaintext message over a WireGuard tunnel that claims to be from host B, then B must have (intentionally) sent this message to A.

Resistance against Key Compromise Impersonation (KCI): Authentication even holds if the static key • of the recipient is compromised.

Resistance against Identity Mis-Binding: If two honest parties derive the same traffic keys in some • WireGuard session, then they agree on each other’s identities, even if one or both of them have been interacting with a compromised host. This property is also called resistance against unknown key-share attacks.

Resistance against Replay: Any protocol message sent may be accepted at most once by the recipient. • Session Uniqueness: There is at most one honest initiator session and at most one honest responder • session for a given traffic key. Similarly, there is at most one honest initiator session and at most one honest responder session for given handshake messages.

Channel Binding: Two sessions that have the same final session transcript hash H share the same view • 7 and the same session keys.

Identity Hiding: Just by looking at the messages transmitted over the network, a passive adversary cannot • infer the static keys involved in a session. (However, these identities are not forward secret.)

DOS Resistance: The adversary cannot have a message accepted by a responder under load without • having first made a round trip with that responder.

89 Deliverable D4.3 NEXTLEAP Grant No. 688722

The security goals above are stated in terms of completed WireGuard sessions, with most security guarantees only applying after the third message, when both the initiator and responder start freely sending and receiving data. In contrast, the Noise specification [7] assigns authentication and confidentiality grades to every protocol message. For IKpsk2, the highest confidentiality grade (perfect forward secrecy to a known recipient) is only reached at the third message. In particular, the first transport data message serves as key confirmation to the responder, and is needed to prove that the initiator has control over its ephemeral key. This is why, in WireGuard, the responder does not send any data until it sees this third message. In the rest of this paper, we investigate whether WireGuard achieves the goals set out above.

3 Cryptographic Assumptions

This section presents the assumptions that we make on the cryptographic primitives used by WireGuard. For most primitives, the desired assumption is already present in the library of primitives of CryptoVerif, so we just need to call a macro to use that assumption. Still, we had to design a new model for Curve25519, detailed below.

3.1 Random Oracle Model

We assume that BLAKE2s is a random oracle [20]. This assumption is justified in [21] using a weak ideal block cipher.

3.2 IND-CPA and INT-CTXT for AEAD

We assume that the ChaCha20Poly1305 AEAD scheme [17] is IND-CPA (indistinguishable under chosen plaintext attacks) and INT-CTXT (ciphertext integrity) [22], provided the same nonce is never used twice with the same key. IND-CPA means that the adversary has a negligible probability of distinguishing encryptions of two distinct messages of the same length that it has chosen. INT-CTXT means that an adversary with access to encryption and decryption oracles has a negligible probability of forging a ciphertext that decrypts successfully and has not been returned by the encryption oracle. These properties are justified in [23], assuming ChaCha20 is a PRF (pseudo-random function) and Poly1305 is ε-almost-∆-universal.

3.3 Curve25519 and Gap Diffie-Hellman

WireGuard uses the elliptic curve Curve25519 [15] for Diffie-Hellman key exchanges. This curve is a group G of order kq where k = 8 (cofactor) and q is a large prime. The base point g has prime order q; we denote by Gsub the prime order subgroup generated by g. In WireGuard and in typical implementations of Curve25519 as specified by RFC 7748 [15], the incoming public keys are not verified, so they may be any element of G and may not belong to Gsub, and all exponents are non-zero multiples of k modulo kq. For each public key X in G, k k there are k public keys Y in G such that X = Y and only one of these public keys is in Gsub. (We write point multiplication exponentially.) We say that public keys X and Y such that Xk = Y k are equivalent, because they z kz kz z yield the same Diffie-Hellman shared secrets: for any exponent z = kz0, X = X 0 = Y 0 = Y . Moreover, the x public keys may be 0, the neutral element of G and Gsub, and 0 = 0 for all x. While most proofs of Diffie-Hellman key agreements assume a prime order group, that assumption is not correct for most implementations of Curve25519. For instance, the identity mis-binding issue that we discuss in Section 6 would not appear in a prime order group. Therefore, we need to provide a new model that takes into account the properties mentioned above.

90 Deliverable D4.3 NEXTLEAP Grant No. 688722

The main idea of our model is to rely on a Diffie-Hellman assumption in the prime order subgroup Gsub, and so to work as much as possible with elements in Gsub. We rewrite the computations in G into computations in Gsub by first raising the public keys to the power k, and we rely on standard properties of prime order groups for Gsub. In CryptoVerif, we first define the following types: type G [bounded,large]. type Gsub [bounded,large]. type Z [bounded,large,nonuniform]. The type G represents the group G; it is bounded because it is represented by bitstrings of bounded length, and large because collisions between randomly chosen elements in G have a negligible probability. Similarly, the type Gsub represents the group Gsub, and the type Z corresponds to non-zero integers multiple of k modulo kq. When honest participants choose exponents, they are chosen uniformly in a subset of Z: they are of the form 2254 + 8n for n 0,...,2251 1 and kq > 2255. Therefore, the distribution for choosing random exponents inside the ∈ { − } whole Z is non-uniform, which is indicated by the annotation nonuniform.

We define functions: fun exp(G,Z) : G. fun mult(Z,Z) : Z. equation builtin commut(mult). We have exp(X,y) = Xy, and mult is the product modulo kq, in Z. Since its two arguments are non-zero multiples of k, so is its result, and it is in Z. The last line states that the function mult is commutative. (We could add associativity and other properties, but commutativity is typically sufficient for basic Diffie-Hellman key exchanges.) fun pow k(G) : Gsub. fun exp div k(Gsub,Z) : Gsub. fun Gsub2G(Gsub) : G [data]. equation forall x : Gsub,x0 : Gsub; (pow k(Gsub2G(x)) = pow k(Gsub2G(x0))) = (x = x0).

k y/k We have pow k(X) = X , and it is in Gsub for all X in G. We have exp div k(X,y) = X . This function operates on Gsub and is convenient since the exponents in Z are always multiples of k. The function Gsub2G is the identity from Gsub to G; it is necessary to convert elements of type Gsub to type G. The annotation data tells CryptoVerif that it is injective. The last equation says that pow k is injective when restricted to the subgroup Gsub, of order q. Indeed, k is prime to q, so it can be inverted modulo q.

We also define constants: const zero : G. const zerosub : Gsub. equation zero = Gsub2G(zerosub). const g : G. const g k : Gsub. equation pow k(g) = g k. equation g k = zero . 6 sub The neutral element is zero as an element of G and zerosub as an element of Gsub. The base point is g, and g k = gk.

We also state equations that hold on these functions: equation forall X : G,y : Z; (1) exp(X,y) = Gsub2G(exp div k(pow k(X),y)). equation forall X : Gsub,y : Z,z : Z; exp div k(pow k(Gsub2G(exp div k(X,y))),z) = (2) exp div k(X,mult(y,z)).

Equation (1) says that Xy = (Xk)y/k and Equation (2) that ((Xy/k)k)z/k = Xy.z/k. Equation (2) applies in particular to simplify exp(exp(X,y),z) after applying (1): exp(exp(X,y),z) = Gsub2G(exp div k(pow k(Gsub2G(exp div k( 91 Deliverable D4.3 NEXTLEAP Grant No. 688722

pow k(X),y))),z)) = Gsub2G(exp div k(pow k(X),mult(y,z))). These equations are used by CryptoVerif as rewrite rules, to rewrite the left-hand side into the right-hand side. They allow to rewrite computations in the group G into computations that happen in the subgroup Gsub, after raising the public key to the power k. In particular, exp(g,y) = Gsub2G(exp div k(g k,y)) and exp(exp(g,y),z) = Gsub2G(exp div k(g k,mult(y,z))). The next equation allows CryptoVerif to simplify equality tests with the neutral element, which are used by some protocols, including WireGuard, to exclude that element from the allowed public keys. equation forall X : Gsub,y : Z; (exp div k(X,y) = zerosub) = (X = zerosub).

When y Z, y = ky for some y not multiple of q, so y is invertible modulo q. Therefore, Xy/k = 0 if and only if ∈ 0 0 0 Xy0 = 0 if and only if (Xy0 )1/y0 = 01/y0 , that is, X = 0.

Other properties serve to simplify equalities between Diffie-Hellman values in Gsub, with the goal of showing that these equalities are false. When the Diffie-Hellman shared secrets are passed to a random oracle, these equality tests appear after using the random oracle assumption: we compare the arguments of each call to the random oracle with arguments of previous calls, to know whether the random oracle should return the result of a previous call. equation forall X : Gsub,X0 : Gsub,y : Z; (3) (exp div k(X,y) = exp div k(X0,y)) = (X = X0). equation forall X : Gsub,y : Z,z : Z; (exp div k(X,y) = exp div k(X,z)) = (4) ((y = z) (X = zero )). ∨ sub R collision x Z;forall X : G ,Y : G ; ← sub sub return(exp div k(X,x) = Y) ≈Pcoll1rand(Z) (5) return((X = zero ) (Y = zero )) sub ∧ sub if X independent-of x Y independent-of x. ∧

Equation (3) holds because y = ky0 for some y0 invertible modulo q as shown above. In particular, using (1), injectivity of Gsub2G, and (3), exp(X,y) = exp(X0,y) simplifies into pow k(X) = pow k(X0). In contrast, in a prime order group, exp(X,y) = exp(X0,y) implies X = X0. This is the reason why, in the identity mis-binding issue of Section 6, we fail to prove equality of the public keys X = X0 and can only prove pow k(X) = pow k(X0). Equation (4) holds because, when X G is different from 0, X is a generator of G , so all elements Xy0 for ∈ sub sub y [1,q 1] are distinct, hence all elements Xy/k as well. 0 ∈ − In the collision statement (5), Pcoll1rand(Z) is the probability that a randomly chosen element x in Z is equal to an element of Z independent of x. For Curve25519, since random exponents are chosen uniformly among a set of 2251 251 elements, Pcoll1rand(Z) = 2− . Statement (5) means that the probability of distinguishing exp div k(X,x) = Y R from (X = zero ) (Y = zero ) is at most Pcoll1rand(Z) assuming X is chosen randomly in Z (x Z) and X sub ∧ sub ← and Y are independent of x. Indeed, suppose that exp div k(X,x) = Y differs from (X = zero ) (Y = zero ). sub ∧ sub If X = 0, then Xx/k = 0, so both expressions reduce to Y = 0, so they cannot differ. Therefore, X = 0. The y 6 second expression is then false. Moreover, X is a generator of Gsub, so Y = X for some y independent of x. The equality Xx/k = Y = Xy holds if and only if x/k = y mod q so x = ky mod kq with ky independent of x, so this happens with probability Pcoll1rand(Z). So the first expression is true with probability Pcoll1rand(Z), and the two expressions differ with that probability. The support for side-conditions in collision statements is an extension of CryptoVerif that we implemented.

Our model includes a few other properties, detailed and justified in the long version of the paper. In particular, it includes properties for simplifying equalities between products in Z. Such equalities appear for instance after simplification of equalities exp div k(g k,mult(x,y)) = exp div k(g k,mult(x0,y0)). For instance, we model that mult(x,y) = mult(x,y0) if and only if y = y0 and that, when x is chosen randomly in Z and y and z are independent of x, it is unlikely that mult(x,y) = z. 92 Deliverable D4.3 NEXTLEAP Grant No. 688722

This model is included as a macro in CryptoVerif’s library of cryptographic primitives, so that it can easily be reused. It also applies to other curves that have a similar structure, for instance Curve448, which is also used by the Noise framework, and by other protocols like TLS 1.3.

We assume that the prime order subgroup Gsub satisfies the gap Diffie-Hellman (GDH) assumption [24]. This assumption means that given a generator g, ga, and gb for random a,b, the adversary has a negligible probability to compute gab, even when the adversary has access to a decisional Diffie-Hellman oracle, which tells him given G,X,Y,Z whether there exist x,y such that X = Gx, Y = Gy, and Z = Gxy. It was already modelled in CryptoVerif.

In contrast, in their cryptographic proof of WireGuard, Dowling and Paterson [12] use the PRF-ODH assumption. We use the GDH and random oracle assumptions instead because CryptoVerif cannot currently use the PRF-ODH assumption in scenarios with key compromise. While in principle the PRF-ODH assumption is weaker, Brendel et al. [25] show that it is implausible to instantiate the PRF-ODH assumption without a random oracle, so our assumptions and the one of [12] are in fact fairly similar.

4 Indifferentiability of Hash Chains

Before modelling WireGuard, we first present a different, equally precise, formulation of hash chains that is more amenable to a mechanised proof in CryptoVerif. Indeed, WireGuard makes a large number of hash oracle calls to BLAKE2s, and at each call to a random oracle, CryptoVerif tests whether the arguments are the same as in any other previous random oracle call (to return the previous result of the random oracle). Therefore, using directly BLAKE2s as a random oracle would introduce a very large number of cases and yield exaggeratedly large cryptographic games. In order to avoid that, we simplify the random oracle calls using indifferentiability lemmas. These lemmas are not specific to WireGuard and can be used to simplify sequences of random oracle calls in other protocols, including other Noise protocols and Signal [6]. In the future, these lemmas may serve as a basis for an indifferentiability prover inside CryptoVerif, which would simplify random oracle calls before proving the protocol.

Specifically, WireGuard uses HKDF in a chain of calls to derive symmetric keys at different stages of the protocol:

C const C hkdf (C ,v ) 0 ← 5 ← 1 4 4 C hkdf (C ,v ) C hkdf (C ,v ) 1 ← 1 0 0 6 ← 1 5 5 C k hkdf (C ,v ) C π k hkdf (C ,v ) 2k 1 ← 2 1 1 7k k 3 ← 3 6 6 C k hkdf (C ,v ) T → T ← hkdf (C ,v ) 3k 2 ← 2 2 2 k ← 2 7 7 C hkdf (C ,v ) 4 ← 1 3 3

We show, using the indifferentiability lemmas of this section, that hkdfn is indifferentiable from a random oracle, and that the chain above is indifferentiable from:

k chain0 (v ,v ) 1 ← 1 0 1 k chain0 (v ,v ,v ) (6) 2 ← 2 0 1 2 π k T → T ← chain0 (v ,v ,v ,v ,v ,v ,v ) k 3k k ← 6 0 1 2 3 4 5 6 Thus, we obtain a much simpler computation, which we use in our CryptoVerif model of WireGuard.

4.1 Definition of Indifferentiability

Indifferentiability can be defined as follows. This definition is an extension of [26] to several independent oracles. We give an asymptotic definition here. In the long version, we give explicit probabilities and proofs for all results.

93 Deliverable D4.3 NEXTLEAP Grant No. 688722

Definition 1 (Indifferentiability). Functions (Fi)1 i n with oracle access to independent random oracles (Hj)1 j m ≤ ≤ ≤ ≤ are indifferentiable from independent random oracles (Hi0)1 i n if for each value of the security parameter η, ≤ ≤ there exists a simulator S that runs in time P1(η) such that for any distinguisher D that runs in time P2(η),

(Fi)1 i n,(Hj)1 j m (Hi0)1 i n,S Pr[D ≤ ≤ ≤ ≤ = 1] Pr[D ≤ ≤ = 1] f (η) | − |≤ where P1 and P2 are polynomials and f is a negligible function. The simulator S has oracle access to (Hi0)1 i n. ≤ ≤ (Fi)1 i n,(Hj)1 j m In the game G0 = D ≤ ≤ ≤ ≤ , the distinguisher interacts with the real functions Fi and the random oracles (Hi0)1 i n,S Hj from which the functions Fi are defined. In the game G1 = D ≤ ≤ , the distinguisher interacts with independent random oracles Hi0 instead of Fi, and with a simulator S, which simulates the behaviour of the random oracles Hj using calls to Hi0. Indifferentiability means that these two games are indistinguishable. We assume that the output length of each random oracle depends only on the security parameter.

4.2 Basic Lemmas

In this section, we show several basic indifferentiability lemmas, which are not specific of WireGuard. Lemma 1 ([27, Lemma 2]). If H is a random oracle, then the functions H1,...,Hn defined as H on disjoint subsets D1,...,Dn of the domain D of H are indifferentiable from independent random oracles, assuming one can determine in polynomial time to which subset Di an element belongs. Lemma 2. The concatenation of two independent random oracles with the same domain is indifferentiable from a random oracle. Lemma 3 ([27, Lemma 3]). The truncation of a random oracle is indifferentiable from a random oracle.

Lemmas 4 and 5 deal with the composition of two random oracle calls in sequence. We extended CryptoVerif to be able to prove indistinguishability between two games given by the user. With this extension, CryptoVerif shows the indistinguishability result between the games G0 and G1 described in Section 4.1, which implies the indifferentiability result. Lemma 4. If H : S S and H : S S S are independent random oracles, then H defined by H (x,y) = 1 1 → 10 2 10 × 2 → 20 3 3 H2(H1(x),y) is indifferentiable from a random oracle. Lemma 5. If H : S S and H : S S S are independent random oracles, then H = H and H defined 1 1 → 10 2 10 × 1 → 20 10 1 20 by H20 (x) = H2(H1(x),x) are indifferentiable from independent random oracles.

4.3 Indifferentiability of HKDF

The hkdf key derivation function is defined as follows [19]:

hkdf (salt,key,info) = k ... k where n 1k k n prk = hmac(salt,key) k = hmac(prk,info i ) 1 k 0 k = hmac(prk,k info i + i ) for 1 i < n i+1 ik k 0 ≤ where n 255, and i = 0x01 and i are of size 1 byte. In WireGuard, info is always empty so we omit it in ≤ 0 Section 2.

We suppose that hmac is a random oracle and we show that hkdfn is indifferentiable from a random oracle, with the additional assumption that the calls to hmac use disjoint domains. (We show that this assumption is necessary and give a full proof of the result in the long version of the paper.) Let S, K , and I be the sets of possible values of salt, key, and info respectively, and M the output of hmac. n 1 Lemma 6. If hmac is a random oracle and K (I i − M I i+i ) = 0/ then hkdf with domain S K I ∩ k 0 ∪ i=1 k k 0 n × × is indifferentiable from a random oracle. S

94 Deliverable D4.3 NEXTLEAP Grant No. 688722

This result extends the proof given for hkdf2 in [27, Lemma 1]. Moreover, our proof is modular and partly made using CryptoVerif, thanks to the basic lemmas of Section 4.2.

Proof sketch. Since the domains are disjoint, by Lemma 1, the (n + 1) calls to hmac are indifferentiable from independent random oracles H0,...,Hn. The constant i + i0 can be removed from the arguments of Hi+1 since it is fixed for a given Hi+1. By Lemma 5, the computation of k2 = H2(H1(prk,info),prk,info) is indifferentiable from a random oracle k = H (prk,info). Applying this reasoning n times, the computation of k for 1 i n 2 20 i ≤ ≤ is indifferentiable from independent random oracles ki = Hi0(prk,info). By Lemma 2, concatenation of Hi0 for 1 i n is indifferentiable from a random oracle H, so hkdf (salt,key,info) = k ... k = H(prk,info), where ≤ ≤ n 1k k n prk = H0(salt,key). By Lemma 4, we conclude that hkdfn is indifferentiable from a random oracle.

4.4 Indifferentiability of a Chain of Random Oracle Calls

In this section, we prove the indifferentiability of a chain of random oracle calls defined as follows. Definition 2 (Chain). Let m 1 be a fixed integer, let C and C with 0 j m + 1 be bitstrings of length l , let ≥ j ≤ ≤ 0 v with 0 j m be bitstrings of arbitrary length, let l be the length of the output of H(C ,v ), and let r with j ≤ ≤ j j j 0 j m be bitstrings of length (l l ).(l and l are functions of the security parameter.) We define the functions ≤ ≤ − 0 0 chain ,0 n < m and the function chain in the following way: n ≤ m

chainn(v0,...,vn) = C = const 0 (7) for j = 0 to n do C r = H(C ,v ) j+1k j j j return rn

chainm(v0,...,vm) = C = const 0 (8) for j = 0 to m do C r = H(C ,v ) j+1k j j j return C r m+1k m The functions chain ,n < m, have an output of length (l l ), and the output length of chain is l. n − 0 m Lemma 7. If H is a random oracle, then chain , for n m, are indifferentiable from independent random oracles. n ≤ We could probably prove this lemma for small values of m using CryptoVerif, but the generic result requires a manual proof because CryptoVerif does not support loops.

4.5 Application to WireGuard

WireGuard employs BLAKE2s [28] both directly as the function hash and indirectly as hash function in hmac and thus also in hkdf. The domains of these two uses are disjoint in WireGuard, as shown by an easy inspection of the length of the arguments. Then by Lemma 1, we can consider two independent random oracles, hash for the direct uses and hash0 for the uses via hkdf. Since hash is a random oracle, it is a fortiori collision-resistant. We use that assumption for hash in our CryptoVerif proof.

Since hash0 is a random oracle, hmac-hash0 is indifferentiable from a random oracle by [29, Theorem 3]. Using Lemma 6, hkdfn is indifferentiable from a random oracle. Since Lemma 7 assumes a chain of calls to the same hkdfn function, we rewrite the chain of hkdf calls in WireGuard to use only calls to hkdf3, as 3 is the maximum number of outputs needed, and discard the unused suffix: by definition of hkdfn, this yields the same result. By Lemma 7, this computation can be replaced with:

k chain (v ,v ) 1k ← 1 0 1 k chain (v ,v ,v ) 2k ← 2 0 1 2 π k chain (v ,v ,v ,v ,v ,v ,v ) k 3 ← 6 0 1 2 3 4 5 6 95 Deliverable D4.3 NEXTLEAP Grant No. 688722

T → T ← chain (v ,v ,v ,v ,v ,v ,v ,v ) k k ← 7 0 1 2 3 4 5 6 7 where concatenates blocks of length the output length of hmac, is an unnamed block, and chain for i 7 are k i ≤ independent random oracles. (The result of chaini for i = 0,3,4,5 is not used.) The output of the random oracles can be truncated by Lemma 3 to avoid having to discard parts of the output. Moreover, in WireGuard, v7 = empty, so T → and T ← only depend on v0,...,v6, as do π and k3 in the previous line. By Lemma 2, we concatenate chain6(...) and chain7(...,empty), and thus obtain (6). The long version of the paper details this proof.

5 Modelling WireGuard

This section presents our model of the WireGuard protocol in CryptoVerif. We prove security properties for that model in Section 6.

5.1 Execution Environment

In our model, we consider two honest entities A and B. In the initial setup, we generate the static key pairs for these two entities and publish their public keys, so that the adversary can use them. After this setup, we run parallel processes that represent a number of executions of A and B polynomial in the security parameter.

The entities A and B can play both the initiator and responder role. These two entities can run WireGuard between each other, but also with any number of dishonest entities included in the adversary: for each session, the adversary sends to the initiator its partner public key, that is, the public key of the entity with which it should start a session; the adversary sends to the responder the set of partner public keys that it accepts messages from.

This setting allows us to prove security for any sessions between two honest entities, in a system that may contain any number of (honest or dishonest) other entities. We prove security for sessions in which A is the initiator and B is the responder. We do not explicitly prove security for sessions in which B is the initiator and A is the responder, but the same security properties hold by symmetry.

The processes for the entities A and B model the entire protocol, including the first two protocol messages, the key confirmation message from the initiator, and then a number of transport data messages polynomial in the security parameter, in both directions between initiator and responder. The model also includes random oracles, and we allow the adversary to call any of the random oracles that we use.

We consider 3 variants of this model:

Variant 1. This variant does not rely at all on the pre-shared key for proving security, so A and B receive a pre-shared key chosen by the adversary at the beginning of each execution. That allows the adversary to model both the absence of a pre-shared key (by choosing the value 0) or a compromised pre-shared key of its choice.

We model the dynamic compromise of the private static key of A (resp. B) by a process that the adversary can call at any time and that returns the private key of A (resp. B) and records the compromise by defining a particular variable, so that it can be tested in the security properties that we consider.

In WireGuard, four Diffie-Hellman operations and the pre-shared key contribute to the session keys. If the pre-shared key is not used or compromised, security is based on the four Diffie-Hellman operations. If one of them cannot be computed by the adversary, then the session keys are secret. Therefore, we consider all combinations of compromises but those where both keys on one side are compromised, that is:

1. A and B’s private static keys may be dynamically compromised;

2. A’s private static key may be dynamically compromised and B’s private ephemeral key is compromised (by sending it to the adversary as soon as it is chosen);

3. B’s private static key may be dynamically compromised and A’s private ephemeral key is compromised; 96 Deliverable D4.3 NEXTLEAP Grant No. 688722

4. A and B’s private ephemeral keys are compromised.

We prove most security properties for clean sessions, that is, intuitively, sessions between honest entities. A session of A is clean when either B’s private static key is not compromised yet and A’s partner public key is equivalent to B’s static public key, or B’s private static key is compromised and the public ephemeral key received by A is equivalent to an ephemeral generated by B. B’s session cleanliness is defined symmetrically. Intuitively, when B’s private static key is not compromised, A can rely on that key to authenticate B, so A thinks she talks to B when she runs a session with B’s public key. We consider a public key equivalent to B’s public key rather than equal to B’s public key to strengthen the properties: the authentication property shown in Section 6 then implies that when A successfully runs a session with a partner public key equivalent to B’s public key, then these two keys are in fact equal. When B’s private static key is compromised, A cannot authenticate B, but we can still prove security when the ephemeral key received by A has been generated by B. Like for static keys, when A successfully runs a session with a received ephemeral equivalent to an ephemeral generated by B, then these two ephemerals are in fact equal.

Variant 2. This variant relies exclusively on the pre-shared key for security. In that variant, we consider all private static and ephemeral keys as always compromised. We choose a pre-shared key randomly in the initial setup, and run sessions between A and B with that pre-shared key. In this model, A’s partner public key is always B’s public key and symmetrically, and these sessions between A and B are always considered clean. The adversary can run A’s and B’s sessions with other entities since A and B’s private static keys are compromised and these sessions use a different pre-shared key.

Variant 3. In this variant, all keys are compromised: all private static and ephemeral keys are always compromised and the pre-shared key is chosen by the adversary for each session. This model is useful for proving properties that do not rely on session cleanliness, that is, properties that hold even for sessions involving dishonest participants.

With this model, we analyse the whole WireGuard protocol as it is, tying together the authenticated key exchange and the transport data phase. A similar approach was chosen by the creators of the Authenticated and Confidential Channel Establishment (ACCE) [30] to analyse TLS. Instead of reasoning about key indistinguishability, ACCE looks at the security of the messages exchanged encrypted using the key. We do the same, for the key confirmation and all subsequent transport data messages.

In ACCE, the adversary has to choose one clean test session in which it tries to break security by determining the secret bit. In all other sessions, it is allowed to reveal the session keys. In our model, all clean sessions are test sessions, and we explicitly reveal the session keys in sessions that are not clean.

5.2 Modelling Tricks

Apart from the HKDF chains where we prove that the way we model them is indifferentiable from the real protocol in Section 4, we use the following modelling tricks:

Timestamps: CryptoVerif has no support for time, so instead of generating the timestamp, we input it from • the adversary. In other words, we delegate the task of timestamp generation to the adversary. In order to model replay protection for the first message, the responder stores a global table (that is, a list) of triples containing the received timestamp, the partner public key for that session, as well as its own public key. (This is equivalent to having a distinct table of timestamps and partner public keys for each responder, represented by its public key.) The responder rejects the first message when the triple (received timestamp, partner public key, and responder public key) is already in the table.

Nonces for the AEAD scheme: The nonces in WireGuard are computed by incrementing a counter. • CryptoVerif has no support for that, so we receive the desired value of the counter from the adversary. We guarantee that the same counter is never used twice in the same session for sending messages by storing

97 Deliverable D4.3 NEXTLEAP Grant No. 688722

all counters used for sending messages in a table of pairs (session index, counter), where the session index identifies the session uniquely: it indicates whether A or B is running, as initiator or as responder, and contains a unique integer index for the execution of that entity in that role. This is equivalent to having a distinct table of counters for each session. The message is not sent when the adversary provides a counter that is already in the table. We guarantee that the same counter is never used twice for receiving messages in the same way, using a separate table.

We omit the MACs mac and mac in our model, since they can be computed and verified by the adversary. • 1 2 We let the adversary choose the key Rr that the responder uses for computing cookies. All other elements needed to compute the MACs are public: constants and static public keys. We reintroduce the MACs in a separate model that we use for proving resistance against DOS.

Importantly, these modelling tricks increase the power of the adversary: the implementation done in WireGuard is a particular case of what the adversary can do in our model, in which the adversary chooses the current time as timestamp, increases the counter for sending messages at each emission, accepts incoming counters in a sliding window, and computes and verifies mac1 and mac2 by itself. As a result, a security proof in our model remains valid in WireGuard.

6 Verification Results

In order to prove authentication properties, we insert events in our model, to indicate when each message is sent or received by the protocol. Specifically, we insert events sent1, sent2, sent msg initiator, and sent msg responder just before sending message 1, message 2, and transport messages on the initiator and responder sides respectively, and corresponding events rcvd1, rcvd2, rcvd msg responder, and rcvd msg initiator when these messages have been received and successfully decrypted. The event rcvd2 and the events for transport messages are executed only in clean sessions.

Mutual key and message authentication, resistance against KCI, resistance against replay from mes- sage 2. We show authentication for all messages starting from the second protocol message, by proving the following correspondence properties between events, in the first two variants of our CryptoVerif model of Section 5.1:

pub pub pub pub inj-event(rcvd2(Sr ,Ei , Si ,Si , ts ,ts, pub Er , empty ,T →,T ←)) pub J pub K pub J K inj-event(sent2(Spub,E , S ,S , ts ,ts, ⇒ r i i i pub J K Er , empty ,T →,T ←)) , J K J K inj-event(rcvd msg responder( J K pub pub pub pub Sr ,Ei , Si ,Si , ts ,ts, pub Er , empty ,T →,T ←,N→, P ,P)) J K J K inj-event(sent msg initiator( ⇒ pub J pub Kpub pub J K Sr ,Ei , Si ,Si , ts ,ts, pub Er , empty ,T →,T ←,N→, P ,P)) , J K J K We also prove a third query (similar to the secondJ one above)K for transportJ dataK messages in the other direction, with events rcvd msg initiator and sent msg responder. A proven correspondence between two injective events (inj-event) means that each execution of the left-hand event corresponds to a distinct execution of the right-hand event.

The first query means that, if the initiator session is clean and the initiator has received the second message,

98 Deliverable D4.3 NEXTLEAP Grant No. 688722 then the responder sent it, and initiator and responder agree on their static and ephemeral public keys, session keys, timestamp, and communicated ciphertexts. This authenticates the responder to the initiator.

The second and third queries mean that, if the receiver session is clean and the receiver received a transport packet, then a sender sent that transport packet, and the receiver and the sender agree on their static and ephemeral public keys, session keys, timestamp, sent plaintext, message counter, and communicated ciphertexts. In particular, for the key confirmation message, this authenticates the initiator to the responder. These queries also provide message authentication for the transport data messages.

All these properties hold when the pre-shared key is not compromised (variant 2 of Section 5.1). They also hold priv priv priv priv when neither both Si and Ei nor both Sr and Er are compromised and the receiver session is clean; this is true, in particular, when the sender’s static private key is not compromised yet (variant 1 of Section 5.1).

The above queries include resistance against replays because the correspondences are injective: each reception corresponds to a distinct emission. They also include resistance against KCI attacks because the rcvd events ∗ are issued even if the receiver’s static key has already been compromised: the receiver session is still clean in this case.

Secrecy and forward secrecy. We show secrecy of transport data messages in clean sessions by a left-or-right message indistinguishability game. In the initial setup, we randomly choose a secret bit. For each transport data message in a clean session, the adversary provides two padded plaintexts of the same length, and we encrypt one of them depending on the value of that bit. CryptoVerif proves the secrecy of that bit, in variants 1 and 2 of Section 5.1, showing that the adversary cannot determine which of the two plaintexts was encrypted.

The secrecy query includes forward secrecy, because we allow dynamic compromise of static keys after the session keys have been established, if the ephemeral key of the same party is not compromised. This assumes that the parties delete the sessions’ ephemeral keys and chaining keys after key derivation.

In variant 2 of our model, the query also shows secrecy provided the pre-shared key is not compromised, even if all other keys (static and ephemeral) are compromised. Our models do not consider the dynamic compromise of the pre-shared key, due to a limitation of CryptoVerif. We can still obtain forward secrecy with respect to the compromise of the pre-shared key using the following manual argument. As mentioned above, variant 2 of our model shows authentication when the pre-shared key is not compromised (all other keys are compromised in this model). This authentication property is preserved when the pre-shared key is compromised after the rcvd ∗ event, because the later compromise cannot alter the fact that the sent event has been executed. Furthermore, ∗ authentication guarantees that the ephemeral public key received by the initiator was generated by the responder and conversely. Variant 1 of our model then guarantees secrecy in this case, because the session is clean when the ephemeral received by the initiator was generated by the responder and conversely. Hence, we get the desired forward secrecy property: we have message secrecy when the pre-shared key is compromised after the priv priv priv priv session, and neither both Si and Ei nor both Sr and Er are compromised. We cannot prove key secrecy for the session keys in the full protocol, because the session keys are used for encrypting transport data messages, and this allows an adversary to distinguish them from fresh random keys. Instead we prove key secrecy for a model in which all transport data messages, including key confirmation, are removed. To prove this result, we need to strengthen the session cleanliness condition. Indeed, the first priv message is subject to a KCI attack: if the private static key of the responder (Sr ) is compromised, then the adversary can forge the first message and impersonate the initiator. Therefore, when the private static key of the responder is compromised, we additionally require that the ephemeral received by the responder is equivalent to one generated by the initiator. With this stronger cleanliness condition, we show that the session keys are secret, that is, the keys for various clean sessions are indistinguishable from independent random keys. We do not need this stronger cleanliness condition when we study the full protocol, since the key confirmation message protects the responder against KCI attacks.

Resistance against replay for the first message. We prove that the first message cannot be replayed but only priv if no static key is compromised when it is received. If Si were compromised, the adversary can impersonate the

99 Deliverable D4.3 NEXTLEAP Grant No. 688722

priv initiator as the sender of this message. If Sr is compromised, we have a KCI attack, as described above. So we prove the following injective correspondence in a model where the static keys cannot be compromised but the ephemeral keys may be compromised, so we rely on the static-static Diffie-Hellman shared secret:

pub pub pub pub inj-event(rcvd1(true,Sr ,Ei , Si ,Si , ts ,ts)) pub pub pub pub inj-event(sent1( Sr ,Ei , Si ,Si , ts ,ts)) . ⇒ J K J K The first parameter of rcvd1 is true if the public static key received by the responder with the first message J K J K is the public static key of the honest initiator: we prove this property only for sessions between honest peers. Replay protection is guaranteed by each timestamp being accepted only once. With this check removed, the first message can be replayed, but we still prove a non-injective correspondence between the two events, replacing inj-event by event in the query. This is a weaker property, meaning that, if an event rcvd1 has been executed, then at least one event sent1 with matching parameters has been executed before. Thus, even with the replay protection removed, we can prove that the origin of the first message cannot be forged in a model without static key compromise.

Correctness. Correctness means that, if the adversary does not modify the first two messages, then the initiator and responder share the same session keys and transcript hash H7. Actually, it suffices that the adversary does not modify the ephemerals and ciphertexts of the first two messages. We prove it with the following query:

pub pub pub event(responder corr(Ei , Si , ts ,Er , empty ,

Tr→,Tr←,Hr7)) J K J K J K event(initiator corr(Epub, Spub , ts ,Epub, empty , ∧ i i r Ti→,Ti←,Hi7)) Ti→ = Tr→ Ti← = Tr← Hi7 = Hr7 . ⇒ J ∧ K J K ∧ J K The events initiator and responder used in this query and in the following ones are issued after key derivation, ∗ ∗ in the initiator and responder respectively. Here, the two events given as assumptions guarantee that the adversary did not modify the ephemerals and ciphertexts of the first two messages, and the query concludes that the session keys and transcript hash must be equal. However, in our main models, CryptoVerif is currently unable to cannot prove that the ciphertexts have not been created by the adversary, although this is true in the sessions considered by the correctness query. Thus, we created a separate model to prove correctness, in which the assumption is hard-coded by interleaving the initiator and responder in a single sequential process. In this model, we prove correctness even if all keys are compromised.

Session Uniqueness. First, we prove that there is a single initiator and a single responder session with a given T → or T ←. The query below shows that there cannot be two distinct initiator sessions with the same T →:

event(initiator uniq T→(ii,T →))

event(initiator uniq T→(i0,T →)) i = i0 , ∧ i ⇒ i i where ii,ii0 are replication indices: CryptoVerif assigns each execution of the initiator (or responder) process a unique replication index, so the query means that if we execute two events initiator uniq T→ with the same T →, then they have the same replication index ii = ii0, hence they belong to the same session. This query is proved in variant 3 of Section 5.1, so the property holds even if all keys are compromised. (It relies on the choice of a fresh ephemeral at each session.) The queries for the other cases are similar.

Second, we show in a similar way that there is a single initiator and a single responder session for a given set of publicly transmitted protocol values.

Channel Binding. We prove channel binding with the query:

event(initiator H7(params,H7)) event(responder H7(params0,H )) params = params0 ∧ 7 ⇒ 100 Deliverable D4.3 NEXTLEAP Grant No. 688722

This query shows that if the initiator and responder have the same value of the session transcript H7, then they share the same value of all session parameters params (static and ephemeral public keys, timestamp, pre-shared key, session keys). This query is also proved in variant 3 of Section 5.1, so the property holds even if all keys are compromised. (It relies on the collision resistance of hash.)

Identity Mis-Binding. For this property, we need to show that if an initiator and a responder session share the same session keys T → and T ←, then they share the same view on the ephemeral and static keys used in that session. This is formalised by the following query:

pub pub pub pub event(responder imb(T →,T ←,Ei,rcvd,Er ,Si,rcvd,Sr )) pub pub pub pub event(initiator imb(T →,T ←,E ,E ,S ,S )) ∧ i r,rcvd i r,rcvd Epub = Epub Epub = Epub ⇒ i i,rcvd ∧ r r,rcvd pub pub pub S = S Spub = S . ∧ i i,rcvd ∧ r r,rcvd priv priv priv priv CryptoVerif proves it in variant 1 of our model, so it holds when neither both Si and Ei nor both Sr and Er are compromised. However, the proof fails when all static and ephemeral keys are compromised: CryptoVerif pub pub pub pub can prove only the weaker property that pow k Si = pow k Si,rcvd and pow k Sr = pow k Sr,rcvd . An adversary can indeed break the equality of public static keys in this case:     pub The adversary instructs A to initiate a session to a public static key Sr 0 equivalent to our model’s honest • pub pub pub pub priv responder public static key: pow k(Sr ) = pow k(Sr ) but Sr = Sr . This is possible because Sr 0 6 0 is compromised. In this session, the adversary acts as responder, and because the ephemeral is also priv compromised, gets A’s Ei . pub The adversary now acts as initiator to start a session with B using a public static key Si 0 equivalent to the • pub pub pub pub honest initiator public static key: pow k(Si ) = pow k(Si 0) but Si = Si 0. This is possible because priv priv 6 Si is compromised. The adversary uses Ei as ephemeral. The ephemeral of this session is also priv compromised, so the adversary gets Er . priv The adversary continues the session with A using the ephemeral Er . • If a pre-shared key is used, we assume that the adversary has the same pre-shared key with A (presenting itself pub pub with key Sr 0) and with B (presenting itself with Si 0). The session keys T → and T ← for these two sessions pub priv priv priv priv pub priv priv priv priv are computed as hashes of Ei , dh(Ei ,Sr ), dh(Si ,Sr ), Er , dh(Ei ,Er ), dh(Si ,Er ), and psk. They are the same in both sessions, so the session keys are also the same.

This scenario, with a session between A and B0 and one between B and A0 that share the same session keys, is an instance of a bilateral unknown key-share attack [31] and of a key synchronisation attack [5]. It appears only when all static and ephemeral Diffie-Hellman keys are compromised, and hence should be considered a corner-case. However, we note that this scenario does not require the psk shared by A and B to be compromised, since this psk does not get used in the execution above. We suggest a possible fix of this identity mis-binding issue in Section 7.

Resistance against DOS. As described in Section 2, WireGuard provides a cookie mechanism that a peer under load can use to enforce a round trip per sender address, and thus to bind a handshake message to a sender address; this permits per-address rate limiting. We model this mechanism in a separate model in which a responder generates Rr, replies with a cookie τ = mac(Rr,Ai) upon receipt of messages 1 from Ai with zero mac2, and verifies mac2 upon receipt of messages 1 with non-zero mac2. The rest of the protocol is run by the adversary, which has the long-term static keys. In particular, we do not model the encryption of the cookie τ, but send it in the clear, assuming that the adversary carries out the encryption and decryption, which depend only on values it knows.

In this model, we prove that, if a responder under load accepts a handshake message from a sender with address Ai, then this sender passed through a roundtrip, that is, the responder did indeed previously generate a cookie for 101 Deliverable D4.3 NEXTLEAP Grant No. 688722

the address Ai. This formalised by the following query:

event(accepted cookie(Ai,ir,τ,msgβ,mac2)) event(generated cookie(A ,i ,τ)) , ⇒ i r where ir is an index that uniquely identifies the key Rr used for generating the cookie. This query is proved under the assumption that mac is a pseudo-random function (PRF).

pub Identity Hiding. When the adversary has a candidate public key SY , it can determine whether this public key is involved in WireGuard sessions, as already mentioned in the WireGuard specification [8]. In the first message, pub pub pub it can test whether mac1 = mac(hash(labelmac1 SY ),msgα) and that reveals whether SY = Sr . A similar pub pub k pub test on message 2 reveals whether SY = Si . When an entity with public key Sm sends a cookie reply, the pub adversary can try to decrypt the encrypted cookie τ with the key hash(label S ), the nonce nonce cookiek Y (obtained from the cookie reply), and the associated data mac1 (obtained from a previous message). If decryption pub pub succeeds, then the adversary knows that SY = Sm .J InK practice, the public keys of VPN endpoints may be easy to obtain: they are often published to subscribers on a web page. In such scenarios, WireGuard does not provide identity hiding.

If we consider the protocol without MACs and cookie reply, that is, basically the Noise protocol IKpsk2, we can obtain stronger identity protection guarantees, however with the additional assumption that the AEAD scheme also preserves the secrecy of the associated data. Indeed, if the AEAD scheme is only IND-CPA and INT-CTXT, pub pub then the adversary may obtain the associated data of the first ciphertext Si , that is, hash(hash(H0 Sr ) pub pub pub pub k k Ei ). It can compare this value with hash(hash(H0 SY ) Ei ) since Ei is sent in the first message and H0 pub k pub k is a constant. Thus, it can determine whether Sr = SY . J K However, assuming that the AEAD scheme also preserves the secrecy of the associated data, we prove using CryptoVerif that the protocol without MACs and cookie reply satisfies the following identity hiding property: an pub pub pub pub adversary that has SA1 , SA2 , SB1 , SB2 cannot distinguish a configuration in which the entity with public key pub pub pub pub SA1 initiates sessions with SB1 from one in which the entity with public key SA2 initiates sessions with SB2 . ChaCha20Poly1305 indeed preserves the secrecy of the associated data, because it satisfies the stronger IND$-CPA property, which requires the ciphertext to be indistinguishable from random bits, as shown in [23].

We discuss possible solutions to strengthen the identity hiding for the protocol with MACs in Section 7.

Proof Guidance and Metrics. CryptoVerif needs to be manually guided to perform these proofs. We sketch the main instructions given to CryptoVerif for proving authentication and message secrecy in variant 1 of our model, with dynamic compromise of the private static keys. The guidance we give to other proofs follow similar ideas.

The first step is to distinguish cases. In the initiator A, we add a test to distinguish whether the partner public key is equivalent to B’s static public key, and whether the received ephemeral is equivalent to an ephemeral generated by B. Similarly, in the responder B, we distinguish whether the partner public key is equivalent to A’s static public key, and whether the received ephemeral is equivalent to an ephemeral generated by A. These case distinctions allow us to isolate Diffie-Hellman shared secrets that the adversary will be unable to compute because both shares come from honest participants. Then, we apply the random oracle assumption for the 3 random oracles chain60 , chain20 , chain10 . For the arguments of these oracles that are Diffie-Hellman shared secrets in the protocol (and thus are in Gsub), we distinguish whether the argument received by the random oracle from the adversary is in Gsub before applying the random oracle assumption. (When it is not in Gsub, it cannot collide with a call coming from the protocol.) Next, we apply the gap Diffie-Hellman assumption; we split the keys generated by chain60 into 4 keys, and apply ciphertext integrity of the AEAD scheme. (For keys that the adversary may have after compromising the static keys, we apply a variant of the ciphertext integrity transformation that allows corruption.) This suffices to obtain authentication. Then we apply the IND-CPA property of the AEAD scheme to prove message secrecy.

In total, we give 36 instructions to CryptoVerif to perform this proof (not counting the instruction to display the current game), and CryptoVerif generates a sequence of 168 games. This proof takes 13 min, the proof of key 102 Deliverable D4.3 NEXTLEAP Grant No. 688722 secrecy with dynamic compromise of private static keys takes 16 min, and the one for identity hiding 17 min on one core of an Intel Xeon 3.6 GHz; these are our longest proofs.

7 Discussion

WireGuard is a promising new VPN protocol that aims to replace IPsec and OpenVPN, and is being considered for adoption within the Linux kernel. We presented a mechanised cryptographic proof for a detailed model of WireGuard using the CryptoVerif prover. Our model accounts for the full Noise IKpsk2 secure channel protocol as well as WireGuard’s extensions for stealthy operation and DOS resistance. We consider an arbitrary number of parallel sessions, with an arbitrary number of transport data messages. Furthermore, we base our proof on a precise model of the Curve25519 group.

We proved correctness, message and key secrecy, forward secrecy, mutual authentication, session uniqueness, channel binding, and resistance against replay, key compromise impersonation, and denial of service attacks. In some cases, our analysis pointed out potential improvements in the protocol.

Adding Public Keys to the Chaining Key Derivation. When analysing WireGuard for Identity Mis-Binding attacks, our analysis uncovered a corner case. Suppose all the Diffie-Hellman keys in a session between two hosts A and B were compromised, but the pre-shared key between them is still secret. Then the adversary can set up a man-in-the-middle attack where A thinks it is connected to B0, B thinks it is connected to A0, but in fact they are both connected to each other, in the sense that the two connections have the same traffic keys, even though they have different static keys.

In particular, once it has set up the session, the adversary can step away and let A and B directly communicate with each other, while retaining the ability to read and modify messages at will. Interestingly, this vulnerability only appears in our precise model of Curve25519; it cannot be detected under a classic Diffie-Hellman assumption.

Although this attack scenario may be quite unrealistic, it points to a theoretical weakness in the protocol that is easy to prevent with a simple modification. Noise IKpsk2 already adds ephemeral public keys to the chaining key derivation; we recommend that the static public keys be added as well. Alternatively, adding the full transcript hash to the traffic key derivation would also prevent this corner case.

Separately, it is also worth noting that adding public keys to the key derivation significantly helps with the cryptographic proof. For example, consider the Noise IK protocol, which is similar to IKpsk2 except that it does not use PSKs, IK does not mix the ephemeral keys into the chaining key, and it turns out that it is much harder for CryptoVerif to verify than IKpsk2, since we now have to reason about mis-matched ephemeral keys. In particular, even if we use a public PSK key of all-zeroes, the IKpsk2 protocol is easier to prove secure than IK. In fact, our recommendation is to add further contextual information to the key derivation. It would not only prevent theoretical attacks, but also make proofs easier.

Balancing Stealth and Identity Hiding. Our analysis also points out that the use of static public keys in mac1 and mac2 in WireGuard negatively affects the identity hiding guarantees provided by IKpsk2. This is a conscious trade-off that WireGuard makes to achieve stealthy operation [8]. However, in deployment scenarios where identity hiding is more important than stealth, we recommend that the protocol use a constant (say all-zeroes) instead of the static public keys to compute the MACs and cookies.

While it is difficult to preserve stealth while hiding the responder’s identity, a modification to the protocol can still hide the initiator’s identity. We recommend that the initiator should send a MAC key (along with the timestamp) in the first handshake message, and the responder should use this MAC key to compute mac1 in the second handshake message. The initiator can verify this MAC to get DOS protection, but its static public key is kept hidden from a network attacker. Essentially, the MAC key acts as an in-session cookie.

Related Work. The use of formal verification tools to analyse real-world cryptographic protocols is now a well-

103 Deliverable D4.3 NEXTLEAP Grant No. 688722 established research area with hundreds of case studies (see e.g. [32]). CryptoVerif itself has been used to analyse modern protocols like Signal [27] and TLS 1.3 [33]. We conclude this paper by comparing our results with closely related work.

WireGuard itself has been formally analysed before. Donenfeld et al. [11] symbolically analyse the IKpsk2 key exchange protocol used by WireGuard for a number of security goals, including identity mis-binding and identity hiding. However, they do not model the MACs or the cookie mechanism, and hence they do not prove DOS resistance. Interestingly, their analysis concludes the absence of identity mis-binding attacks even if all keys are compromised, which we disprove, by considering a precise model of Curve25519.

Dowling et al. [12] present a manual cryptographic analysis of WireGuard. In particular, they prove key indistin- guishability for the WireGuard handshake based on the PRF-ODH assumption in an extension of the eCK-PFS key exchange model. Key indistinguishability no longer holds once the key is used, so they prove security for a slightly modified variant of the IKpsk2 protocol that includes a key confirmation message independent from the session keys. In contrast, our proof requires no changes to the protocol, since we use an ACCE-style model. Furthermore, [12] focuses only on the key exchange, and does not consider other properties like identity hiding or DOS resistance. Their analysis also does not find the identity mis-binding issue since they do not consider a scenario where all Diffie-Hellman keys are compromised.

Finally, the Noise Explorer tool [34] has been used to perform a comprehensive symbolic analysis of a large number of Noise protocols using the ProVerif analyser. Noise Explorer can be used to find violations of secrecy and authentication properties for any protocol expressed in the language defined by Noise. It includes a symbolic analysis of Noise IK, and an analysis for Noise IKpsk2 is underway.

References

[1] S. Kent and K. Yao, “Security Architecture for the Internet Protocol,” 2005, IETF RFC 4301.

[2] E. Rescorla, “The Transport Layer Security (TLS) Protocol Version 1.3,” 2018, IETF RFC 8446.

[3] K. Bhargavan and G. Leurent, “On the practical (in-)security of 64-bit block ciphers: Collision attacks on HTTP over TLS and OpenVPN,” in ACM CCS’16, 2016, pp. 456–467.

[4] B. Beurdouche, K. Bhargavan, A. Delignat-Lavaud, C. Fournet, M. Kohlweiss, A. Pironti, P. Strub, and J. K. Zinzindohoue, “A messy state of the union: Taming the composite state machines of TLS,” in IEEE S&P (Oakland), 2015, pp. 535–552.

[5] K. Bhargavan, A. Delignat-Lavaud, C. Fournet, A. Pironti, and P. Strub, “Triple handshakes and cookie cutters: Breaking and fixing authentication over TLS,” in IEEE S&P (Oakland), 2014, pp. 98–113.

[6] M. Marlinspike and T. Perrin, “The X3DH key agreement protocol,” Nov. 2016, available at https://signal.org/ docs/specifications/x3dh/.

[7] T. Perrin, “The Noise protocol framework,” Jul. 2018, https://noiseprotocol.org/noise.html.

[8] J. A. Donenfeld, “WireGuard: Next generation kernel network tunnel,” in Network and Distributed System Security Symposium, NDSS, 2017.

[9] B. Blanchet, “Modeling and verifying security protocols with the applied pi calculus and ProVerif,” Foundations and Trends in Privacy and Security, vol. 1, no. 1-2, pp. 1–135, Oct. 2016.

[10] S. Meier, B. Schmidt, C. Cremers, and D. A. Basin, “The TAMARIN prover for the symbolic analysis of security protocols,” in Computer Aided Verification, CAV’13, ser. LNCS, vol. 8044. Springer, 2013, pp. 696–701.

[11] J. A. Donenfeld and K. Milner, “Formal verification of the WireGuard protocol,” 2018, https://www.wireguard. com/papers/wireguard-formal-verification.pdf. 104 Deliverable D4.3 NEXTLEAP Grant No. 688722

[12] B. Dowling and K. G. Paterson, “A cryptographic analysis of the WireGuard protocol,” in Applied Cryptography and Network Security, ACNS 2018, ser. LNCS, vol. 10892. Springer, 2018, pp. 3–21.

[13] B. Blanchet, “A computationally sound mechanized prover for security protocols,” IEEE Transactions on Dependable and Secure Computing, vol. 5, no. 4, pp. 193–207, Oct.–Dec. 2008.

[14] ——, “Computationally sound mechanized proofs of correspondence assertions,” in IEEE CSF’07, Jul. 2007, pp. 97–111, extended version available at http://eprint.iacr.org/2007/128.

[15] A. Langley, M. Hamburg, and S. Turner, “Elliptic curves for security,” Jan. 2016, IETF RFC 7748.

[16] M.-J. Saarinen and J.-P. Aumasson, “The BLAKE2 cryptographic hash and message authentication code (MAC),” 2015, IETF RFC 7693.

[17] Nir, Yoav and Langley, Adam, “ChaCha20 and Poly1305 for IETF Protocols,” Jun. 2018, IETF RFC 8439.

[18] D. J. Bernstein, “Extending the Salsa20 nonce,” 2011, https://cr.yp.to/snuffle/xsalsa-20110204.pdf.

[19] H. Krawczyk and P. Eronen, “HMAC-based extract-and-expand key derivation function (HKDF),” 2010, IETF RFC 5869.

[20] M. Bellare and P. Rogaway, “Random oracles are practical: a paradigm for designing efficient protocols,” in ACM CCS’93. ACM Press, 1993, pp. 62–73.

[21] A. Luykx, B. Mennink, and S. Neves, “Security analysis of BLAKE2s modes of operation,” IACR Transactions on Symmetric Cryptology, vol. 2016, no. 1, pp. 158–176, Dec. 2016.

[22] M. Bellare and C. Namprempre, “Authenticated encryption: Relations among notions and analysis of the generic composition paradigm,” in ASIACRYPT’00, ser. LNCS, vol. 1976. Springer, Dec. 2000, pp. 531–545.

[23] G. Procter, “A security analysis of the composition of ChaCha20 and Poly1305,” Cryptology ePrint Archive, Report 2014/613, 2014, https://eprint.iacr.org/2014/613.

[24] T. Okamoto and D. Pointcheval, “The gap-problems: a new class of problems for the security of cryptographic schemes,” in PKC 2001, ser. LNCS, vol. 1992. Springer, Feb. 2001, pp. 104–118.

[25] J. Brendel, M. Fischlin, F. Gnther, and C. Janson, “PRF-ODH: Relations, instantiations, and impossibility results,” in CRYPTO 2017, ser. LNCS, vol. 10403. Springer, Aug. 2017, pp. 651–681.

[26] J.-S. Coron, Y. Dodis, C. Malinaud, and P. Puniya, “Merkle-Damgard˚ revisited: How to construct a hash function,” in CRYPTO 2005, ser. LNCS, vol. 3621. Springer, 2005, pp. 430–448.

[27] N. Kobeissi, K. Bhargavan, and B. Blanchet, “Automated verification for secure messaging protocols and their implementations: A symbolic and computational approach,” in IEEE EuroS&P’17, Apr. 2017, pp. 435–450.

[28] J.-P. Aumasson, S. Neves, Z. Wilcox-O’Hearn, and C. Winnerlein, “BLAKE2: Simpler, smaller, fast as MD5,” in Applied Cryptography and Network Security. Springer, 2013, pp. 119–135.

[29] Y. Dodis, T. Ristenpart, J. Steinberger, and S. Tessaro, “To hash or not to hash again? (in)differentiability results for H2 and HMAC,” in CRYPTO 2012. Springer, 2012, pp. 348–366, full version at https://eprint.iacr. org/2013/382.

[30] T. Jager, F. Kohlar, S. Schage,¨ and J. Schwenk, “On the security of TLS-DHE in the standard model,” in CRYPTO 2012, ser. LNCS, vol. 7417. Springer, 2012, pp. 273–293.

[31] L. Chen and Q. Tang, “Bilateral unknown key-share attacks in key agreement protocols,” Journal of Universal Computer Science, vol. 14, no. 3, pp. 416–440, Feb. 2008.

[32] B. Blanchet, “Security protocol verification: Symbolic and computational models,” in Principles of Security and Trust, POST’12, ser. LNCS, vol. 7215. Springer, 2012, pp. 3–29.

105 Deliverable D4.3 NEXTLEAP Grant No. 688722

[33] K. Bhargavan, B. Blanchet, and N. Kobeissi, “Verified models and reference implementations for the TLS 1.3 standard candidate,” in IEEE S&P (Oakland), 2017, pp. 483–502.

[34] N. Kobeissi and K. Bhargavan, “Noise Explorer: Fully automated modeling and verification for arbitrary Noise protocols,” Cryptology ePrint Archive, Report 2018/766, Aug. 2018, https://eprint.iacr.org/2018/766, the tool is available at https://noiseexplorer.com/.

106 Deliverable D4.3 NEXTLEAP Grant No. 688722

------First ------pub priv pub E : (E ,E ) $ keygen() i i i ← C hash(protocol name) 0 ← Initiator i Responder r H hash(C prologue) 0 ← 0k pub pub 16 pub First(Ii,Ei , Si , ts ,mac1,mac2 = 0 ) H hash(H S ) 1 ← 0k r Second(I ,I ,Epub, empty ,mac ,mac = 016) pub r i rJ K J K 1 2 C1 hkdf1(C0,Ei ) , , ← → → pub TransportData(Ii,N1→, P1 ) H hash(H E ) J K 2 ← 1k i priv priv  TransportData(I ,N , P )  C k hkdf (C ,dh(E ,S )) r 2← J 2K 2k 1 ← 2 1 i r pub pub pub TransportData(I ,N , P ) S : S aenc(k ,0,S ,H ) i 3→ J 3K i i ← 1 i 2 pub ··· H3 hash(H2 Si ) J K J K J K ← k priv priv C3 k2 hkdf2(C2,dh(Si ,Sr )) Figure 1a: WireGuard’s protocol messages. k ← J K ts : ts aenc(k ,0,timestamp(),H ) ← 2 3 H hash(H ts ) 4 ← 3k macJ K : macJ K mac(hash(label Spub),msg ) 1 1 ← mac1k r α ------Second -- --J --K ------pub priv pub Responder r E : (E ,E ) $ keygen() Initiator i r r r ← pub 16 C hkdf (C ,E ) First(Ii,...,mac1,mac2 = 0 ) 4 ← 1 3 r pub H5 hash(H4 E ) CookieReply(Ii,nonce, τ ) ← k r priv priv First(I ,...,mac ,mac ) C5 hkdf1(C4,dh(Er ,Ei )) i 1 J2 K ← C hkdf (C ,dh(Epriv,Spriv)) (continues with standard handshake) 6 ← 1 5 r i C π k hkdf (C ,psk) 7k k 3 ← 3 6 H6 hash(H5 π) ------CookieReply ------← k empty : empty aenc(k3,0,empty,H ) 256 6 R $ 0,1 (refresh only every 2 minutes) ← r ← { } H hash(H empty ) 7 ← 6k τ mac(Rr,Ai) with Ai = IPi Porti J K J K ← k pub 192 mac1 : mac1 mac(hash(labelmac1 Si ),msgα) nonce $ 0,1 ← J K k ← { } pub ------Key Derivation ------τ xaenc(hash(labelcookie Sr ),nonce,τ,mac1) ← k T → T ← hkdf (C ,empty) k ← 2 7 ------Non-zero mac2 ------J K ------TransportData ------mac mac(τ,msg ) 2 β P aenc(T →,N→ = 0,P ,empty) ← 1 ← 1 1 Figure 1c: Cookie mechanism under load. P2 aenc(T ←,N2← = 0,P2,empty) J K ← P3 aenc(T →,N3→ = 1,P3,empty) J K ← Figure 1b: CryptographicJ K Computations for Protocol Messages.

Figure 1: An overview of WireGuard’s main protocol messages (1a), the cryptographic computations used these messages (1b), and the cookie mechanism used by WireGuard to protect hosts against Denial-of-Service attacks (1c). msgα refers to all the bytes of a message up to but not including mac1, msgβ is the same but including mac1. Session key derivation takes places after the second protocol message, symbolised by , , at which point the → initiator can send messages. The end of the handshake is symbolised by , after which transport data messages can be sent in both directions. The cookie mechanism is depicted in one direction, initiator to responder, but can actually be used by either initiator or responder, whichever is under load.

107