Availability is crucial to the security of distributed systems, but guaranteeing availability is hard, especially when participants in the system may act maliciously. Quorum replication protocols provide both integrity and availability: data and computation is replicated at multiple independent hosts, and a quorum of these hosts must agree on the output of all operations applied to the data. Unfortunately, these protocols have high overhead and can be difficult to calibrate for a specific application’s needs. Ideally, developers could use high-level abstractions for consensus and replication to write fault-tolerant code that is secure by construction.
This paper presents Flow-Limited Authorization for Quorum Replication (FLAQR), a core calculus for building distributed applications with heterogeneous quorum replication protocols while enforcing end-to-end information security. Our type system ensures that well-typed FLAQR programs cannot fail (experience an unrecoverable error) in ways that violate their type-level specifications. We present noninterference theorems that characterize FLAQR’s confidentiality, integrity, and availability in the presence of consensus, replication, and failures, as well as a liveness theorem for the class of majority quorum protocols under a bounded number of faults. Additionally, we present an extension to FLAQR that supports secret sharing as a form of declassification and prove it preserves integrity and availability security properties.
Failure is inevitable in distributed systems, but its consequences may vary. The consequences of failure are particularly severe in centralized system designs, where single points-of-failure can render the entire system inoperable. Even distributed systems are sometimes built using a single, centralized authority to execute security-critical tasks. If this trusted entity is compromised, the security of the entire system may be compromised as well.
Building reliable decentralized systems, which have no single point-of-failure, is a complex task. Quorum replication protocols such as Paxos [16] and PBFT [7], and blockchains such as Bitcoin [21] replicate state and computation at independent hosts and use consensus protocols to ensure the integrity and availability of operations on system state. In these protocols, there is neither centralization of function nor centralization of trust: all honest hosts work to replicate the same computation on the same data, and this redundancy helps the system tolerate a bounded number of node failures and corruptions.
Within a single trust domain such as a corporate data center, replicas likely have uniform trust relationships and may be treated interchangeably. However, many large-scale systems depend on services hosted by multiple external services. Even when a service’s internal components are replicated, developers must take into account the failure properties of external dependencies when considering their own robustness.
Information flow control (IFC) has been used to enforce decentralized security in distributed systems for confidentiality and integrity (e.g., Fabric [18] and DStar [28]). Less attention has been paid to enforcing decentralized availability policies with IFC. In particular, no language (or protocol) we are aware of addresses systems that compose multiple quorums or consider quorum participants with arbitrary trust relationships.
To build a formal foundation for such languages, we present FLAQR, a core calculus for Flow-Limited Authorization [3] for Quorum Replication. FLAQR uses high-level abstractions for replication and consensus that help manage tradeoffs between the availability and integrity of computation and data.
Integrity-availability trade-off.
Consider the scenarios in Fig. 1. Shaded boxes represent hosts in a distributed system. Dashed lines denote outputs that contribute to the final result, a value v. Dotted lines denote ignored outputs and solid lines indicate the flow of data from an initial expression e distributed to hosts to the collected result. Results are accompanied by labels that indicate which hosts influenced the final result.
In Fig. 1(b), e is distributed to hosts and . The hosts’ results are compared and, if they match, the result is produced. Since a value is output only if the values match, we can treat the output of this protocol as having more integrity than just or . While both and technically influence the output, neither host can unilaterally control its value. However, either host can cause the protocol to fail.
By contrast, the protocol in Fig. 1(a) prioritizes availability over integrity: if either or produce a value, the protocol outputs a value – in this case ’s. Here, neither host can unilaterally cause a failure; the protocol only fails if both and fail. Either or (but not both) has complete control over the result in the event of the other’s failure, so we should treat the output as having less integrity than just or .
With an adequate number of hosts, we can combine these two techniques to form the essential components of a quorum system. In Fig. 1(c), e is replicated to , , and . This protocol outputs a value if any two hosts have matching outputs. Since and both output v, the protocol outputs v and attaches and ’s signatures. The non-matching value from is ignored. Hence, this protocol prevents any single host from unilaterally controlling the failure of the protocol or its output.
Figure 1(c) is similar in spirit to consensus protocols such as Paxos or PBFT where quorums of independent replicas are used to tolerate a bounded number of failures. FLAQR also permits us to write protocols where principals have differing trust relationships. Figure 1(d) illustrates a protocol that tolerates failure (or corruption) of either or , but requires ’s output to be part of any quorum. This protocol will fail if both and fail to produce matching outputs, but can also fail if fails to produce a matching output. This example illustrates the distributed systems where the hosts do not have homogeneous trust.
The main contributions of this paper are:
An extension of the static fragment of the Flow Limited Authorization Model (FLAM) [3] with availability policies and algebraic operators representing the effective authority of consensus and replication protocols (Section 3–Section 5).
A formalization of the FLAQR language (Section 4) and accompanying results:
A liveness theorem for majority-quorum FLAQR protocols (Section 7.1) which experience a bounded number of faults using a novel proof technique: a blame semantics that associates failing executions of a FLAQR program with a set of principals who may have caused the failure.
Noninterference theorems for confidentiality, integrity, and availability (Section 7.2).
An extension to FLAQR adding support for simple secret sharing, and results demonstrating it preserves integrity and availability noninterference as well as our liveness theorem, despite introducing an additional source of failure due to mismatched shares (Section 9).
This paper is an expanded and updated version of an article previously published in the proceedings of the 35th Computer Security Foundations Symposium [19]. This version adds support for secret sharing (Section 9) and extensions of our previous results that demonstrate these new terms neither impact integrity and availability noninterference, nor majority liveness, despite introducing an additional source of failure. In addition, we corrected a minor issue in the original blame semantics, and include complete rule sets and proofs for our formalization and theoretical results.
Non-goals. The design of FLAQR is motivated by application-agnostic consensus protocols such as Paxos [16] and PBFT [7], but our present goal is not to develop a framework for verifying implementations of such protocols (although it would be interesting future work). Rather, the goal is to develop security abstractions that make it easier to create components with application-specific integrity and availability guarantees, and compose them in a secure and principled way.
In particular, the FLAQR system model lacks some features that a protocol verification model would require, most notably a concurrent semantics, asynchronous message delivery, and arbitrary communication patterns. Although this simplifies some aspects of consensus protocols, our model retains many of the core challenges present in fault tolerance models. For example, perfect fault detection is impossible and faulty hosts can manipulate data to cause failures to manifest at other hosts. We argue that even in a synchronous, deterministic model with RPC-style communication, the challenges of specifying and enforcing policies remain quite difficult to solve, and are among the primary security concerns of high-level application developers.
Motivating examples
In this section we present two motivating examples. The first example highlights the trade-off between integrity and availability. The second example highlights the need for availability policies in distributed systems.
Tolerating failure and corruption
If a bank’s deposit records are stored in a single node, then customers will be unable to access their accounts if that node is unavailable or is compromised. To eliminate this single point-of-failure, banks can replicate their records on multiple hosts as illustrated in Fig. 1(c). If a majority of hosts agree on an account balance, then the system can tolerate the remaining minority of hosts failing or returning corrupted results.
Consider a quorum system with three hosts: , , and . To tolerate the failure of a single node, balance queries attempt to contact all three hosts and compare the responses. As long as the client receives two responses with the same balance, the client can be confident the balance is correct even if one node is compromised or has failed.
Majority quorum.
Figure 2 illustrates a pseudocode implementation of in this system. The code fetches balances from the three hosts (lines 2–4). The function returns the balance if each fetched value matches, otherwise the function returns (lines 6–12).
The downside of this approach is that it is quite verbose and repetitive compared to a single-line fetch without any fault tolerance. Small mistakes in any of these lines could have significant consequences. For example, suppose a programmer typed instead of on line 8. This small change gives (or an attacker in control of ’s node) the ability to unilaterally choose the return value of the function, even when and agree on a different value.
Using best available services
Real world applications often consist of communication between entities with mutual distrust. The pseudocode in Fig. 3 communicates with two banks, represented by and , during a distributed computation. A user has two accounts , and with and respectively. The user has linked both accounts to a service and specifies the bill should be paid
as long as at least one account is available
using the highest-balance account, if available
Lines 7–10 take care of point (1), ensuring the comparison on line 12 does not get stuck if a returns . Lines 12–15 cover point (2), returning the account with the highest balance when both balances are available.
Available largest balance.
This example shows how availability of data can effect the final result of an application and thus highlights the importance of enforcing availability in distributed computations. As in the previous example, the programmer must reason about failures due to unavailable hosts and make the correct comparisons to implement the (implicitly) desired policy. Furthermore, the programmer may be unaware of the availability guarantees offered by and . For example, if and rely on the same replicas to implement , the availability of may be lower than expected.
Finally, in both of the above examples, an attacker should not be able to read an account balance, or infer which account balance was greater. With the FLAQR type-system, programmers can not only specify and enforce availability and integrity, but also confidentiality – crucial for dealing with sensitive information. Moreover, FLAQR enables programmers to write fault-tolerant code concisely, with explicit primitives for consensus and replication operations that clarify the programmer’s intentions.
Specifying FLAQR policies
FLAQR policies are specified using an extension of the FLAM [2,3] principal algebra that includes availability policies.2
Specifically, we extend the static fragment of FLAM’s principal algebra defined by FLAC [2].
FLAM principals represent both the authority of entities in a system as well as bounds on the information flow policies that authority entails. For example, Alice’s authority is represented by the principal . Authority projections allow us to refer to specific categories of Alice’s authority. The principal refers to Alice’s confidentiality authority: what Alice may read. Principal refers to Alice’s integrity authority: what Alice may write or influence.3
Prior FLAM-based formalizations have used → and ← for confidentiality and integrity, respectively.
Principal refers to her availability authority: what Alice may cause to fail. A principal always acts for any projection of its authority, so for example . We refer to the set of all primitive principals such as and as .
We can write the conjunction of two principals with the Boolean connective ∧ as , denoting the combined authority of Alice and Bob. Put another way, is a principal both Alice and Bob trust. The disjunction of two principals’ authority is written using the connective ∨ as . This is a principal whose authority is less than both Alice and Bob; either Alice or Bob can act on behalf of the principal . Put another way is a principal that trusts both Alice and Bob. Authority projections distribute over ∧ and ∨, so for example .
The confidentiality, integrity, and availability authorities make up the totality of a principal’s authority, so writing is equivalent to writing . For brevity, we sometimes write as a shorthand for when we wish to include all but one kind of authority. Our complete formalization of the acts-for relation is presented in Figs 39 and 40 in Appendix A.
In addition to conjunctions and disjunctions of authority, FLAQR also introduce two new operators: partial conjunction (), and partial disjunction (). These operations are necessary to represent the tradeoffs between integrity and availability mediated by consensus and replication. Consider the “more integrity” protocol from Fig. 1(b). It is reasonable to think of the consensus value v as having more integrity than (or at least, “not less integrity than”) Alice or Bob alone, but it turns out to be useful to distinguish between this authority and the combined integrity authority of Alice and Bob, (). A principal with integrity authority () may act arbitrarily on behalf of both Alice and Bob since it is trusted by them. In contrast, the integrity of the value produced in Fig. 1(b) is not fully trusted by Alice and Bob. Instead, Alice and Bob only trust the value when Alice and Bob agree on it. If they do not agree, that trust is revoked and no value is produced. For this reason, we describe the integrity of consensus values such as v as the partial conjunction of Alice and Bob, written .
Similarly, for replication protocols like that in Fig. 1(a), we want to distinguish the integrity of values that may have been received from either Alice or Bob due to failure, from the integrity of values that may have been influenced by both Alice and Bob: . The integrity of a value produced by either Alice or Bob is written as the partial disjunction. This principal does not have the same integrity authority as Alice or Bob alone since we cannot guarantee which host’s value will be used in the event of a failure. However, the value does have more integrity than , since only Alice or Bob (and not both) may have influenced it.
We compare the authority of principals using the acts-for relation ≽, which partially orders (equivalence classes of) principals by increasing authority. We form the set of all principals as the closure of the set over the operations ∧, ∨, , , and authority projections , , and . We say Alice acts for Bob (or equivalently, Bob trusts Alice) and write when Alice has at least as much authority as Bob. The ≽ relation forms a lattice with join ∧, meet ∨, greatest element ⊤, and least element ⊥.
In addition to the trust relationships such as and implied by the principal algebra, explicit delegations of trust such as (for any p, q in ) may expressed using a delegation context Π. An acts-for judgment has the form and means that p acts for q in context Π. While FLAC has a feature that allows dynamic extensions of Π, for simplicity we fix Π to a static set of delegations in FLAQR.
Selected acts-for rules for partial conjunction and disjunction.
The FLAQR authority lattice for the principal set .
We extend the acts-for relation defined by Arden et al. [2] with new rules for availability authority and partial conjunction and disjunction. Figure 4 presents a selection of these rules – we have omitted the distributivity rules for brevity. In Fig. 4, an acts for judgement of form , states that p has at least as much authority as q in delegation context Π. Figures 39 and 40 in Appendix A together present the complete formalization of the ≽ relation. In Fig. 40 we present only the extensions to this relation introduced by FLAQR.
As a consequence of these new acts-for rules we have additional distinct points in the authority lattice. Figure 5 illustrates the authority sublattice over elements . Figure 5 shows the trust ordering of all possible distinct combinations of elements that can be formed on the set with operations ∧, ∨, and over them. The relationship between principals , and ⊤ is the same as in FLAM, but Fig. 5 also includes principals constructed using partial conjunctions and disjunctions. For example, is the least upper bound of and . This is due to rule PAndPOr in Fig. 4, which lets us simplify to .
To compare the restrictiveness of information flow policies, we use the flows-to relation ⊑, which partially orders principals by increasing policy restrictiveness, rather than by authority. For example, we say Alice’s integrity flows to Bob’s integrity and write if Bob trusts information influenced by Alice at least as much as information he influenced himself. Likewise, we write if Alice trusts Bob to protect the confidentiality of her information, and if Bob is trusted to keep Alice’s data available. The flows-to relation behaves similarly to a sub-typing relation. Treating information labeled (i.e. ) as though it was labeled (i.e. ) is only safe (doesn’t violate anyone’s policies) if (i.e. ).
One advantage of the FLAM principal algebra is that we can define the flows-to relation, as well as the upper and lower bounds of information flow policies, in terms of the acts-for relation, simplifying our formalism.
Based on this, the equivalence classes of ≽ and ⊑ are identical, meaning that the lattice formed by ⊑ with joins ⊔ and meets ⊓ has the same elements as the acts-for lattice. A flow from p to q is secure only when is at least as confidential as , trusts information influenced by , and cannot cause failures that cannot.
FLAQR syntax and semantics
FLAQR syntax. Shaded terms are new to FLAQR. Underlined terms are used during evaluation and not available at the source level.
FLAQR local semantics.
FLAQR evaluation context.
Figures 6 and 7 present the FLAQR syntax and selected evaluation rules. Figure 8 presents the evaluation context. For space and exposition purposes, we omit some term annotations and standard lambda calculus rules in order to focus on FLAQR’s contributions, but the complete, annotated FLAQR syntax and semantics can be found in Figs 29 and 31 in the Appendix.
FLAQR is based on FLAC [2,5], a monadic calculus in the style of Abadi’s Polymorphic DCC [1]. In addition to standard extensions to System F [12,13,23] such as pairs and tagged unions, an Abadi-style calculus supports monadic operations on values in a monad indexed by a lattice of security labels. Such a value has a type of the form , meaning that it is a value of type τ, protected at level ℓ, where ℓ is an element of the security lattice. Here we focus on FLAQR’s additions to FLAC and DCC, and refer the readers to Figs 33 and 34 in the Appendix for our complete formalization.
FLAQR builds on FLAC’s expressive principal algebra and type system to model distributed security policies for applications that use replication and consensus. FLAC supports arbitrary policy downgrades through dynamic delegations of authority, but for simplicity we omit these features in FLAQR.
The monadic unit or return term protects the value that e evaluates to at level ℓ (E-Sealed).4
Polymorphic DCC does not define a term similar to and thus does not have an rule equivalent to E-Sealed. This approach enables us to distinguish where a value may be created (e.g., on a host authorized to read and create values protected at ℓ) and use more permissive rules to control where a sealed value may flow.
Protected values, cannot be operated on directly. Instead, a bind expression must be used to bind the protected value to a variable whose scope is limited to the body of the bind term (E-BindM). The body performs the desired computation and “returns” the result to the monad, ensuring the result is protected. These rules (E-Sealed and E-BindM) FLAQR inherits from FLAC. The remaining rules of Fig. 7 are specific to FLAQR.
The primary novelty in the FLAQR calculus is the introduction of and terms for expressing consensus and replication operations. We represent the consensus problem as a comparison of two values with the same underlying type but distinct outer security labels. In other words, we want to check the equality of values produced by two different principals. If the values match, we can treat them as having the (partially) combined integrity of the principals. If not, then the principals failed to reach consensus.
Rule E-Compare defines the former case: two syntactically equal values protected at different labels evaluate to a value that combines labels using the compare action on labels . Intuitively, determines the increase in integrity and the corresponding decrease in availability inherent in requiring a consensus. We define formally in Definition 1.
(Compare action on principals).
We also lift this notation to types by defining
As discussed in Section 3, the integrity authority of is not as trusted as the conjunction of and ’s integrity. Instead, we represent the limited “increase” in integrity authority5
Strictly speaking, is not an increase in integrity over x (or y); and x are incomparable.
using a partial conjunction in Definition 1. In contrast, the decrease in availability is represented by a (full) since either or could unilaterally cause the compare expression to fail.
propagation rules.
The decreased availability resulting from applying is more apparent in rules E-CompareFail, E-CompareFailL and E-CompareFailR. In E-CompareFail, two unequal values are compared, resulting in a failure. Failure is represented syntactically using a term. We use a type annotation τ on many terms in our formal definitions so that our semantics is well defined with respect to failure terms, but we omit most of these annotations in Fig. 7. These annotations are only necessary for our formalization and would be unnecessary in a FLAQR implementation.
A term may also result in failure if either subexpression fails. Rule E-CompareFailL and E-CompareFailR, defines how failure of an input propagates to the output. In fact, most FLAQR terms result in failure when a subexpression fails. Figure 9 presents selected failure propagation rules (complete failure propagation rules are presented in Fig. 32). Note that terms are treated similarly to values, but are distinct from them. For example, in E-AppFail, applying a lambda term to a fail term substitutes the failure as it would a value, but in E-SealedFail the failure is propagated beyond the monadic unit term. This latter behavior captures the idea that failures cannot be hidden or isolated in the same way as secrets or untrusted data.
Failures are tolerated using replication. A term will evaluate to a value as long as at least one of its subexpressions does not fail. For example, rule E-SelectL returns its left subexpression when the right subexpression fails. In contrast to , applying increases availability since either subexpression can be used, but reduces integrity since influencing only one of the subexpressions is potentially sufficient to influence the result of evaluating . The effect of a statement on the labels of its sub-expressions is captured with the select action.
(Select action on principals).
We define the select action on types similarly to compare:
The end result of a select statement, , will have integrity of either or since only one of the two possible values will be used. We use a partial disjunction to represent this integrity since the result does not have the same integrity as or , but does have more integrity than since it is never the case that both principals influence the output.
Global semantics.
Global configuration stack.
Global semantics
We capture the distributed nature of quorum replication by embedding the local semantic rules within a global distributed semantics defined in Fig. 10. This semantics uses a configuration stack (Fig. 11) to keep track of the currently executing expression e, the host on which it is executing c, and the remainder of the stack t. We also make explicit use of the evaluation contexts from Fig. 7 to identify the reducible subterms across stack elements.
The core operation for distributed computation is which runs the computation e of type τ on node p. Local evaluation steps are captured in the global semantics via rule E-DStep. This rule says that if e steps to locally, then steps to globally.
Rule E-Run takes an expression e at host c, pushes a new configuration on the stack containing e at host and places an term at c as a place holder for the return value.
Once the remote expression is fully evaluated, rule E-RetV pops the top configuration off the stack and replaces the term at c with the protected value . Rule E-RetFail serves the same purpose for terms, but is necessary since terms are not considered values (see Fig. 6). The label reflects both the integrity and availability context of the caller (c) as well as the integrity and availability of the remote host (). We discuss this aspect of remote execution in more detail in Section 5.
FLAQR typing rules
Typing rules for expressions.
As we have a local and global semantics, we have two corresponding forms of typing judgements: local typing judgments for expressions and global typing judgments for the stack. Local typing judgments have the form . Π is the program’s delegation context and is used to derive acts-for relationships with the rules in Figs 4 and 40. Γ is the typing context containing in-scope variable names and their types. The label tracks the information flow policy on the program counter (due to control flow) and on unsealed protected values such as in the body of a .
Figure 12 presents a selection of local typing rules. Each typing rule includes an acts-for premise of the form . This enforces the invariant that each host principal c has control of the program it executes locally. Thus for any judgment should never exceed the authority of c, the principal executing the expression. Rules Fail and Expect type and terms according to their type annotation τ. Rule Lam types lambda abstractions. Since functions are first-class values, we have to ensure that the annotation on the lambda term preserves the invariant . The clearance of a type τ, written , is an upper bound on the annotations of the function types in τ. By checking that holds (along with similar checks in Run and Ret), we ensure the contents of the lambda term is protected when sending or receiving lambda expressions, and that hosts never receive a function they cannot securely execute. Due to space constraints, the definition of is presented in Appendix A, in Fig. 35. The App rule requires the pc label at any function application to flow to the function’s pc label annotation. Hence the premise .
Protected terms are typed by rule UnitM as where τ is the type of e. Additionally, it requires that . This ensures that any unsealed values in the context are adequately protected by policy ℓ if they are used by e. The Sealed rule types protected values . These values are well-typed at any host, and does not require since no unsealed values in the context could be captured by the (closed) value v.
Computation on protected values occurs in bind terms . The policy protecting e must be at least as restrictive as the policy on so that the occurrences of x in e are adequately protected. Thus, rule BindM requires , and furthermore e is typed at a more restrictive program counter label to reflect the dependency of e on the value bound to x.
Rule Run requires that the at the local host flow to the of the remote host, and that e be well-typed at , which implies that acts for . Additionally, c must act for the clearance of the remote return type to ensure c is authorized to receive the return value. The type of the run expression is , which reflects the fact that controls the availability of the return value and also has some influence on which value of type is returned. Although may not be able to create a value of type unless flows to , if has access to more than one value of type , it could choose which one to return. Rule Ret requires that expression e is welltyped at c and that is authorized to receive the return value based on the clearance of τ.
The Compare rule gives type to the expression where and have types and respectively. Additionally, it requires that c, the host executing the , is authorized to fully examine the results of evaluating and so that they may be checked for equality.6
Assuming a more sophisticated mechanism for checking equality that reveals less information to the host such as zero-knowledge proofs or a trusted execution environment could justify relaxing this constraint.
This requirement is captured by the premise , pronounced “c reads”. The inference rules for the reads judgment are found in Fig. 37 in Appendix A.
Finally, the Select rule gives type to the expression where and have types and respectively.
The typing judgment for the global configuration is presented in Fig. 13 and consists of three rules. Rule Head shows that the global configuration , is well-typed if the expression e is well-typed at host c with program counter where and the tail t is well-typed. means that the tail of the stack is of type τ while the expression in the head of the configuration is of type . We introduced rules Tail(when ) and Emp(when ) to typecheck the tail t.
is well-typed with type , if expression is well-typed with type at host c. And, the rest of the stack t needs to be well-typed with type . Rule Emp says the tail is empty and the type of the expression in the head of the configuration is τ, in which case the type of the whole stack is .
Typing rules for configuration stack.
Availability attackers
Availability attackers are different from traditional integrity and confidentiality attackers. While an integrity attacker’s goal is to manipulate data and a confidentiality attacker’s goal is to learn secrets, an availability attacker’s goal is to cause failures. In our model, an availability attacker can substitute a value only with a term. Integrity attackers may also cause failures in consensus based protocols when consensus is not reached because of data manipulation. In FLAQR this scenario is relevant during executing a statement: if one of the values in the statement is substituted with a wrong (mismatching) value then a term is returned. Thus we need to consider an availability attacker’s integrity authority when reasoning about its power to a program. Specifically, the authority of principal ℓ as an availability attacker is .
We consider a static but active attacker model similar to those used in Byzantine consensus protocols. By static we mean which principal or collection of principals can act maliciously is fixed prior to program execution. By active we mean that the attackers may manipulate inputs (including higher-order functions) during run time. We formally define the power of an availability attacker with respect to quorum systems.
Availability attackers in FLAQR are somewhat different than integrity and confidentiality attackers because we want to represent multiple possible attackers but limit which attackers are active for a particular execution. This goal supports the bounded fault assumptions found in consensus protocols where system configurations assume an upper bound on the number of faults possible.
A quorum system is represented as set of sets of hosts (or principals) e.g. . Here each represents a set of principals whose consensus is adequate for the system to make progress. We define availability attackers in terms of the toleration set of a quorum system . The toleration set is a set of principals where each principal represents an upper bound on the authority of an attacker the quorum can tolerate without failing.
The toleration set for quorum is ,
For heterogeneous quorum system the toleration set is
For the toleration set is , i.e. can not tolerate any fault.
An availability attacker’s authority is at most equivalent to a (single) principal’s authority in the toleration set. We define the set of all such attackers for a quorum as
which includes weaker attackers who a principal in the toleration set may act on behalf of.
The fails relation (⋗) determines whether a principal can cause a program of a particular type to evaluate to . Similar to the reads judgment, the fails judgment not only considers the outermost principal, but also any nested principals whose propagated failures could cause the whole term to fail. Figure 14 defines the fails judgment, written , which describes when a principal l can fail an expression of type τ in delegation context Π.
Consider an expression and an attacker principal . If , and , then the attacker learns nothing by evaluating . Similarly, if and , then the attacker cannot influence the value .
In contrast, if , and , an availability attacker may cause to evaluate to , which steps to by E-SealedFail. The fails relation reflects this possibility. Using A-Type and A-Avail ( or A-IntegCom if was of form ) we get .
Fails judgments.
We use the fails relation and the attacker set to define which availability policies a particular quorum system is capable of enforcing. We say guards τ if the following rule applies:
(Valid quorum type).
A type τ is a valid quorum type with respect to quorum system and delegation set Π if the condition is satisfied.
If and then is not a valid quorum type because as and . But it is a valid quorum type for heterogeneous quorum system as .
Security properties
To evaluate the formal properties of FLAQR, we prove that FLAQR preserves noninterference for confidentiality, integrity, and availability (Section 7.2). These theorems state that attackers cannot learn secret inputs, influence trusted outputs, or control the failure behavior of well-typed FLAQR programs. In addition, we also prove additional theorems that formalize the soundness of our type system with respect to a program’s failure behavior.
Soundness of failure
FLAQR’s semantics uses the and security abstractions and the failure propagation rules to model failure and failure-tolerance in distributed programs, and FLAQR’s type system lets us reason statically about this failure behavior. To verify that such reasoning is sound, we prove two related theorems regarding the type of a program and the causes of potential failures.
In pursuit of this goal, this section introduces our blame semantics which reasons about failure-causing (faulty) principals during program execution. The goal is to record the set of principals which may cause run-time failures as a constraint on the set of faulty hosts . Figure 15 presents the syntax of blame constraints, which are boolean formulas representing a lower bound on the contents of . Atomic constraints denote that label ℓ is in faulty set . This initial blame constraint () is represented using the toleration set of the implied quorum system.
Blame constraint syntax.
Blame membership: to apply C-In, C-Or and C-And the label p needs to be a primitive principal in . The blame semantics rules ensure all statements added to the blame set only refer to primitive principals. This rule set differs from the originally published one [19], which didn’t correctly handle compound principals such as .
(Initial blame constraint).
For toleration set of the form , …, the initial blame constraint is defined as a (logical) disjunction of conjunctions:
Each disjunction represents a minimal subset of a possible satisfying assignment for the faulty set . For brevity, we will refer to these subsets as the possible faulty sets implied by a particular blame constraint. Observe that for quorum system , there is a one-to-one correspondence between every and every possible faulty set in where is the set implied by the ith disjunction in such that , where .
Evaluation rule C-CompareFail, in Fig. 17, shows how function (discussed below) updates the blame constraint from to . We omit the blame-enabled versions of other evaluation rules since they simply propagate the blame constraint without modification.
E-CompareFail with blame semantics.
Quorum system has toleration set and three possible faulty sets in : or or
Quorum system has toleration set and two possible faulty sets in : or .
While is defined statically according to the type of the program, rule C-CompareFail updates these constraints according to actual failures that occur during the program’s execution. This approach identifies “unexpected” failures not implied by .
For example, has two possible faulty sets or . The initial blame constraint is
Placing blame for a specific failure in a distributed system is challenging, (and often impossible!). For example, when a comparison of values signed by and fails, it is unclear who to blame since either principal (or a principal acting on their behalf) could have influenced the values that led to the failure. We do know, however, that at least one of them is faulty; recording this information helps constrain the contents of possible faulty sets.
We can reason about principals that must be in by considering all possible faulty sets implied by the blame constraints. We write (read as entails), when every possible faulty set in , has the clause. Figure 16 presents inference rules for the ⊨ relation.
The rules C-In, C-Or and C-And are defined for a primitive principal in , where . Whereas rules C-Conj, C-Disj, C-ParAnd and C-ParOr are defined for compound principals such as and . The blame semantics rules (particularly, the and functions) ensure all statementss added to the blame set only refer to primitive principals. This rule set differs from the rule set presented in the originally published one [19], which didn’t correctly handle compound principals such as . For example, if and , then with the old ruleset from [19], we can not prove , because the blame semantics did not add the compound principal to . Instead the blame semantics add and to the blame set as two different statements. But with our corrected ruleset we can prove , given and (using C-Conj and C-In).
Let us see another example. Since is included in all satisfying choices of below, we can say (using C-Conj,C-In, and possibly C-In).
The function (full definition in Fig. 45) is used by rule C-CompareFail to update . For an expression:
with , updates the formulas in to reflect that either or is faulty. If or already must be faulty, specifically if or , then the function does not update any formulas. This approach avoids blaming honest principals when the other principal is already known to be faulty.
If neither nor are known to be faulty. then function is called recursively on inner layers (i.e., nested expressions) of and until a subexpression protected by a known-faulty principal is found. If no such layer is present, then the principal protecting the innermost layer is added to (or the outer principals if there are no inner layers). Only this principal has seen the unprotected value and thus could have knowingly protected the wrong value. Observe that for well-typed expressions, only the outer layer of d terms may differ in protection level, so there is less ambiguity when blaming an inner principal.
Updated constraints are kept in disjunctive normal form. Specifically, for compared terms and , with , with initial constraint: , then returns
We can now state the soundness theorem for our blame semantics, and apply it to prove a liveness result. Theorem 1 states that for any well-typed FLAQR program with a failing execution, and the faulty sets implied by (the final constraint computed by the blame semantics), it must be the case that the program’s type τ reflects the ability of the (possibly colluding) principals in to fail the program.
then for each possible faulty setimplied by, there is a principalsuch that.
Either e takes single step or multiple steps to produce the term as the end result. For both the cases we prove it by induction over structure of e. See Appendix B for full proof. □
While Theorem 1 characterizes the relationship between a program’s type and the possible faulty sets for a failing execution, it does not explicitly tell us anything about the fault-tolerance of a particular program. Since the type of a FLAQR program specifies its availability policy (in addition to its confidentiality and integrity), different FLAQR types will be tolerant of different failures. Below, we prove a liveness result for a common case, majority quorum protocols.
(Majority quorum system).
An majority quorum system is a quorum system that always requires at least m of its hosts to reach consensus, where .
(Majority Liveness).
If e is a source-level expression and:
is amajority quorum system
then for every possible faulty setimplied by,.
From (2), we know τ is a valid quorum type for so . Since is a superset of , we also have . Furthermore, from Definition 4, for each possible faulty set implied by , we know there is a principal such that , where . Therefore, for each such , we know .
Since is an majority quorum system, every quorum is of size m and every faulty set in is of size . For contradiction, assume there exists a faulty set satisfying that has size . Then by the definition of , all possible faulty sets implied by also have size since monotonically increases the size of all possible faulty sets or none of them. Furthermore, each possible faulty set implied by is a subset (or equal to) a possible faulty set implied by , so implies .
From Theorem 1 we know for every possible faulty set implied by , it must be the case that , where . However, since , we have a contradiction since (2) implies . Thus there cannot exist a possible faulty set of size (at least) implied by , and all possible faulty sets must have size greater than . □
Noninterference
We prove noninterference by extending the FLAQR syntax with bracketed expressions in the style of Pottier and Simonet [22]. Figure 43 shows selected bracketed evaluation rules and Fig. 42a and 42b show the typing rules for bracketed terms. The soundness and completeness of the bracketed semantics are proved the Appendix A (Lemmata 16–21).
Noninterference often is expressed with a distinct attacker label. We use H to denote the attacker. This means the attacker can read data with label ℓ if and can forge or influence it if and can make it unavailable if
An issue in typing brackets is how to deal with terms. Our confidentiality and integrity results are failure-insensitive in the sense that they only apply to terminating executions. This is similar to how termination-insensitive noninterference is typically characterized for potentially non-terminating programs.
Traditionally, bracketed typing rules require that bracketed terms have a restrictive type, ensuring that only values derived from secret (or untrusted) inputs are bracketed. In FLAQR, there are several scenarios where a bracketed value may not have a restrictive type. For example, when a expression is evaluated within a bracket, it pushes an element onto the configuration stack, but only in one of the executions. Another example is when a bracketed value occurs in a expression, but the result is no longer influenceable by the attacker H. For these scenarios, several of the typing rules in Fig. 42a permit bracketed values to have less restrictive types. Because of these rules, subject reduction does not directly imply noninterference as it does in most bracketed approaches, but the additional proof obligations are relatively easy to discharge.
The table above summarizes how bracketed terms are typed depending on whether we are concerned with integrity or availability. For integrity, unequal bracketed values must have a restrictive type (i.e., one that protects H), but equal bracketed values may have a less restrictive type. For availability, only bracketed terms where one side contains a value and the other a failure must have a restrictive type.
Confidentiality and integrity noninterference
To prove confidentiality (integrity) noninterference we need to show that given two different secret (untrusted) inputs to an expression e the evaluated public (trusted) outputs are equivalent. Equivalence is defined in terms of an observation function adapted from FLAC [2] in Appendix A, Fig. 44.
(- Noninterference).
Ifwhere
,
and,.
then,
From subject reduction we can prove that and have same type. By induction over the structure of projected values, , we can show Please refer to the Appendix A for full proof. □
Availability noninterference
Similar to [30] our end-to-end availability guarantee is also expressed as noninterference property. Specifically, if one run of a well-typed FLAQR program running on a quorum system terminates successfully (does not fail), then all other runs of the program also terminate.
This approach treats “buggy” programs where every execution returns regardless of the choice of inputs as noninterfering. This behavior is desirable because here we are concerned with proving the absence of failures that attackers can control. For structured quorum systems with a liveness result such as Theorem 2 for majority quorums, we can further constrain when failures may occur. For example, Theorem 2 proves failures can only occur when more than principals are faulty. In contrast, Theorem 4 applies to arbitrary quorum systems provided they guard the program’s type, but cannot distinguish programs where all executions fail.
(Availability Noninterference).
Ifwhere
andand
then
From subject reduction (see Lemma 25 in the Appendix) we know, . Because and we can write from rule Q-Guard. This ensures if , then , and vice-versa. □
Examples revisited
We are now ready to implement the examples from Section 2 with FLAQR semantics. To make these implementations intuitive we assume that our language supports integer () types, a mathematical operator > (greater than), and ternary operator . Beacuse is a base type returns ⊥. The examples also read from the local state of the participating principals. Which is fine because there are standard ways to encode memory (reads/writes) into lambda-calculus.
Tolerating failure and corruption
In this FLAQR implementation (Fig. 18) of majority quorum example of Section 2.1, we refer principals representing , and as a, b and c respectively. The program is executed at host with program counter . Which means condition holds. The program body consists of a function of type () and the three arguments to the function are statements. Here τ is . Which means . The function body can be evaluated at , as condition is true.
FLAQR implementation of majority quorum example.
Here , and are the expressions that read the balances for account from the local states of a, b and c respectively. The program counter at a, b, and c are a, b and c respectively. The data returned from a has type , which is basically . Similarly is and is . Because each returns a balance, the base type of τ is an type, and it is protected with confidentiality label , meaning anyone who can read all the three labels (a, b and c), can read the returned balances.
In order to typecheck the statements the conditions , , and need to hold. The condition is trivially true as . Similarly and as well.
The host executing the code need to be able to read the return values from the three hosts. This means conditions and need to hold in order to typecheck the statements. The type of the whole program is , which is a valid quorum type for .
Based on the security properties defined in Section 7 this program offers the confidentiality, integrity and availability guaranteed by quorum system . Therefore, the result cannot be learned or influenced by unauthorized principals, and will be available as long as two hosts out of a, b, and c are non-faulty.
The toleration set here is . So, the program is not safe against an attacker with label (or, ), for example. This is because . Since , principal can fail two statements on lines 3 and 8. And, because , can also fail another two statements (one overlapping statment) on lines 3 and 6. Thus the whole program evaluates to . This FLAQR code also helps prevent incorrect comparisons. For instance, replacing z with y on line 8 will not typecheck.
FLAQR implementation of available largest balance example.
Using best available services
The code in Fig. 19 is the FLAQR implementation of Fig. 3. The program runs at a host c with program counter . The expressions e and read account balances from principals b and , representing the banks. The values returned from b and have types and respectively.
The type of the whole program is . Here . In order to typecheck the statements, the conditions and need to hold. The program counter at b is b and is . The bind statements (lines 3–4) typecheck because conditions , , , and hold, because of our choice of d.
Secret sharing with FLAQR
Secret sharing is a cryptographic mechanism used in several distributed systems protocols such as oblivious transfer, multiparty communication, and Byzantine agreement. In this section we extend FLAQR with two new language constructs to support secret sharing. We call this extended version of our programming model FLAQR. Secret sharing is a process of splitting a secret into n shares and distributing the shares among n hosts (or principals in our setting). When an adequate number of hosts, say t, combine their respective shares, the secret is reconstructed [10,24]. Sometimes this process is referred as (t,n)-threshold secret sharing scheme [24,26], i.e. a quorum of t hosts (where ) out of those n hosts need to combine their shares to retrieve the initial secret value. With or fewer shares, adversaries learn nothing about the secret.
Secret sharing is most commonly described in terms of a mathematical polynomial, say , of degree , being the secret value [24]. The polynomial’s values at n different co-ordinates are distributed as the secret shares, and by knowing t of these values one can reconstruct8
For simplicity, we extend FLAQR to support (2,2)-threshold secret sharing, but later sketch how support for (t,n)-threshold secret sharing where and would be straightforward. We model secret shares abstractly using a value sealed by new kinds of principals and . We call k a key principal because, unlike the principals in , a new, unique key principal k is created each time secret shares are created. In contrast, the principals in are statically known. The principals and represent the two associated shares of the key principal k. We will be refering to (2,2)-threshold secret sharing simply as (2,2) secret sharing in the following sections.
Motivating example of secret sharing : Password splitting
Figure 20 presents a simple (2,2) secret sharing example and the corresponding pseudocode is shown in Fig. 21. A (secret) password belongs to who wants keep a backup of it. Bob creates two secret-shares of as and and sends them to and respectively. That is, anyone who wants to get access to has to either get it directly from , or needs to get both and from and and reproduce it. Later, fetches the secret shares from and and combines them to produce the password .
An advantage of secret sharing is that it permits the secure transmission of secrets without requiring key distribution or public-key infrastructure (PKI). Instead, any party who possesses t shares may recover the secret. This can also be a liability, however, since an adversary needs to only obtain the shares to access the secret, too. Thus, considering the flow of shares between principals is central to the security of a secret sharing scheme. In the example in Fig. 21, and are unable to access the secret because they only possess a single share, but a coding error could transmit both shares to or , obviating the cryptographic protection. For this reason, embedding secret sharing in a language like FLAQR makes sense because the type system ensures the code only permits authorized flows.
Overview of secret sharing: shares his secret shares with and . Later, and forward their respective shares to . Finally, reproduces the initial secret with the shares he received from and .
Creating two secret shares from a secret and then reconstructing the secret from the two secret shares using functions of a secret sharing protocol.
secret sharing in FLAQR
Our abstractions for secret sharing in FLAQRmake use of the term to represent sealed secret shares. However, aspects of secret sharing schemes differ from the use of in prior FLAC-based languages [2,8,14]. Here, in addition to the sealed values generated by the term, sealed values may also be created when splitting a secret into shares. In the previous approaches, a value sealed by serves as a reasonable model for signed and encrypted values. Specifically, the confidentiality component behaves like a public-key encrypted value: anyone can encrypt values at , but only authorized parties (which possess the associated private key) can distinguish the values protected at . Since can only be applied in contexts where (see UnitM), the integrity component behaves like a digitally signed value: only authorized principals can cause a value to be signed with integrity, but anyone can use high-integrity values.9
There doesn’t appear to be a natural cryptographic analog for the availability component.
Obviously then, enforcing these policies cryptographically would require public-key infrastructure.
Secret sharing behaves differently from the above interpretations: rather than authorization being based on possession of a long-lived private key (a reasonable proxy for identity), secret sharing implicitly authorizes any party possessing t shares. Therefore using identity-based principals such as or is inappropriate since, even if a shared secret is intended for , anyone with t shares will be able to distinguish the secret. Even must have t shares to access the secret. An abstraction for secret sharing should capture this behavior, but doing so in FLAQRrequires new concepts.
We extend the set of principals with new primitive principals L and R representing the left and right shares of our secret sharing scheme. The set of all principals for FLAQRis thus the closure of the set over the same operations as FLAQR. In the following we are only interested in the confidentiality projections and , since secret sharing only concerns enforcing the confidentiality of the secret.
Another aspect of secret sharing that departs from prior uses of FLAC principals is that each time shares are created, they are protected by a different secret. Consequently, shares created from different invocations cannot be mixed, even when the underlying value is the same. For this reason, we define key principals, a new type of principal generated dynamically at runtime. For our purposes, each , where is the set of all key principals, is equipped with a left and right principal, and . Importantly, since key principals are generated dynamically, they are not directly representable statically. The principals and are the static representation for the left and right principals of any key principal, but the shares of different key principals cannot be distinguished at the type level.
Semantics and types for secret sharing
FLAQR+ semantics for secret sharing (splitting secrets and combining shares).
FLAQR+ typing rules for secret sharing.
Figure 22 presents the semantic rules added to FLAQR. Expression produces two secret shares, sealed with principals and from the secret value v (rule E-Split) using a fresh key principal k. The ℓ annotation specifies an additional policy to seal the secret with an addition to the key principal. Primarily ℓ is used for integrity and availability components since and are confidentiality projections.
Two shares are combined with expression
Rule E-Combine evaluates these terms to revealing the secret v and substituting it for x in the body e. Notice that the key principal is the same on both sides of the pair. As discussed below in Section 9.4, mismatched key principals result in failure. The additional annotation on combine terms is used by the extended blame semantics, discussed in Section 9.4.
For simplicity, our extension only supports (2,2)-threshold secret sharing, but we believe extending this framework to support (t,n)-threshold secret sharing for and would be straightforward. For example, given some t and n, we could redefine E-Split to generate a tuple containing n shares sealed by principals . E-Combine would be replaced by rules: one for each valid t-sized subset of shares.
Figure 23 presents the FLAQR typing rules for and . The last premise in the Split rule involves the view of the ’s integrity, . The view of a principal was introduced by Ceccetti et al. [8] to specify an upper bound on the confidentiality that may be robustly declassified [27] based on the integrity of the context performing the declassification and the data itself. These restrictions ensure an attacker cannot influence what (or whether) information is declassified. Below, we extend the definition of view with the principals’ availability projection counterpart as well.
(view of a principal).
Let be a FLAM [3] label (principal) expressed in normal form. The view of ℓ, written as , is defined as .
The premise in Split serves two purposes. First, it ensures the confidentiality of control flow and the unsealed values in the context, represented by , are no more restrictive than the upper bound on declassification (or the confidentiality of ℓ if no declassification takes place). Second, it ensures the label ℓ protects the availability and integrity of the context; only confidentiality may be downgraded by terms.
When shares are combined to reveal the secret, the rule Combine ensures the combined pair contains a left and right share (although not which key principal they are associated with), and that the body of the term protects the result with a principal at least as restrictive as the upper bound of ℓ and the context the occurs in.
In some sense, and function as an alternative to and . The difference is that seals values using a key principal in addition to a label ℓ, and permits secrets more restrictive than ℓ to be sealed. Combine is similar to a that declassifies its bound value, dropping the key principals and from the protection requirements on the body of the . Note that it is not possible for a type-safe program to a secret share. Since a premise of bind would require the body accessing the unsealed share on host c to typecheck at , this would violate the invariant that c must act for the of the programs it executes.10
Recall this invariant is enforced by the premise included in all typing rules.
We need one more typing rule, SealedK, to preserve the types of the values sealed with labels and , for any freshly generated key . The existing Sealed rule is not enough as it does not handle the values protected with these new key principals. A consequence of this rule is that well-typed FLAQR programs can produce mismatching shares with two different keys (say and ) during run-time. We handle mismatching shares with our extended blame semantics, discussed in Section 9.4.
Extending the blame semantics
As with other FLAQR terms, values propagate through and . Figure 24 presents fail propagation rules for and statements. These rules are straightforward propagation rules except for E-CombineFail (see Figure 25), which evaluates to if the key principals sealing the shares are mismatched.
propagation rules in FLAQR.
E-CombineFail with blame semantics.
The introduction of E-CombineFail rule creates an additional source of failure besides terms with mismatched values. Rule C-CombineFail extends FLAQR’s blame semantics to account for this. Unlike the case for , we cannot blame the failure on the principal that sealed the mismatched values given to . The failure in this case is due to pairing together shares generated by different evaluations. Rather than blaming the creators of the sealed value, we instead want to blame the principals that influenced this pairing. This influence is represented by the label of the . Hence, when and do not match, C-CombineFail adds to the blame set. The function used in C-CompareFail is unnecessary here because it is unnecessary to examine any subterms of the combined pair – only the outer key principals contribute to a failure.
This normalization function was not present in the original FLAQR publication [19], which is an error. Normalization of the statements added to the blame set is required to ensure compound principals are correctly handled.
in the premise of C-CombineFail is used to add the new (potentially malicious) principal in the exisiting blame set in normalized form. For example, if and if , then calling will return a blame set
In case of C-CompareFail (Fig. 17), the function was called from within the function (see Fig. 45). Figure 46 contains the complete definition of the function.
Security properties
By design, and are interfering with respect to confidentiality: they can cause secret values to be declassified. However, we would like to ensure that integrity and availability noninterference are unaffected.
In order to prove integrity and availability noninterference for FLAQR programs we extend the bracketed semantics (Fig. 26) and observation function (Fig. 27) with rules for and , and add the corresponding cases for and terms to the proofs for the lemmas and theorems of FLAQR. The noninterference theorem statements for FLAQR are identical to Theorems 3 and 4, though Theorem 3 only holds for in FLAQR. Since the new static principals L and R are only used in confidentiality projections, rules such as Q-Guard and the fails are unaffected by the new terms for secret sharing, the proofs of these theorems is largely unchanged from those for FLAQR. However, ensuring the new terms did not break an essential lemma such as subject reduction (Lemma 24) required careful design of the new rules for evaluation, failure propagation, bracketed semantics, and typing.
Although we protect the robustness (in theory) of what values may be declassified via and , secret sharing is inherently non-robust since the party possessing the shares decides whether to reveal the secret. To formalize the protections that and do offer, a weaker form of robust declassification would be required that permits secure uses of and prohibits insecure ones (such as those violating the premise ). Such a definition is not immediately clear12
One reason such a definition is challenging in FLAC-based languages is that the label not only protects control flow, but also any values that have been unsealed using (which raises the label for its body).
to us, and we leave further investigation to future work. Since and permit non-robust declassification, they could potentially permit malleability attacks [8]. Since secret shares cannot be unsealed via , the possibility for such attacks is limited, but we leave formalization of the strength of these limitations to future work.
For statements, failures are generated because of two mismatching values. In contrast, the contents of the secret shares are irrelevant in statements. Instead, failures happen due to mismatching keys of the secret shares. Hence, we should only blame the control flow of the program for putting the two mismatching secret shares together. Since the program counter tracks the control flow of the program, we blame the program counter annotation in the C-CombineFail rule by adding it to the blame set when a term is returned while combining two shares. Our Theorem 1 (Sound blame) still holds, even though statement adds a new source of failure. The new cases hold because the premise in Combine allows us to show (using P-Lbl and A-Avail). Since, Theorem 1 holds, Theorem 2 (Majority liveness) holds as well, as it depends on Theorem 1.
Bracketed semantics for FLAQR terms.
Observation function for intermediate FLAQR terms (extended from FLAC [2]).
Password splitting example with FLAQR
Figure 28 presents the FLAQRimplementation of the example discussed in Section 9.1. The program executes at host with program counter , such that . The host a has program counter a, host b has program counter b and host c has program counter c. The program consists of a function body (lines 1–5) and an argument to it (line 6). The function body is of type , where = , and takes the value of running a statement at host b (i.e. ), which splits b’s secret v. The argument type is . This means the pair of the secret shares created at and returned by b is tainted with b’s integrity and availability. In order to typecheck the statement needs to flow to b, i.e. the condition needs to hold. The condition satisfies trivially, as . The function body can be executed at as and we mentioned earlier that the condition is true. The statements on line 3 and 4 indicates that the left share is tainted by a’s and the right share is tainted by c’s integrity and availability. Which means a and c have seen and approved on the secret shares created by b. To make the statements on lines 3 and 4 well-typed, the conditions should satisfy. We choose label ℓ such that . The statements (lines 2–4) typecheck because the conditions , and hold due to our choice of ℓ.
A simple example of secret sharing in FLAQR.
Related work
FLAM [3,4] offers an algebra to integrate authorization logics and information flow control policies. FLAM also introduces a security condition, robust authorization, that is useful to ensure security when delegations and revocations change the meaning of confidentiality and integrity policies. In FLAQR we extend FLAM algebra with availability policies, and new binary operations to represent integrity and availability policies of the output of quorum based protocols. FLAC [2,5] embeds its types with FLAM information flow policies. FLAC supports dynamic delegation of authority, but this feature is omitted in FLAQR.
A limited number of previous approaches [29,30] combine availability with more common confidentiality and integrity policies in distributed systems. Zheng and Myers [29] extend the Decentralized Label Model [20] with availability policies, but focus primarily tracking dependencies rather than applying mechanisms such as consensus and replication to improve availability and integrity. Zheng and Myers later introduce the language Qimp [30] with a type system explicitly parameterized on a quorum system for offloading computation while enforcing availability policies. Instead of treating quorums specially, FLAQR quorums emerge naturally using and and enable application-specific integrity and availability policies that are secure by construction.
Hunt and Sands [15] present a novel generalisation of information flow lattices that captures disjunctive flows similar to the influence of replicas in FLAQR on a result. Our partial-or operation was inspired by their treatment of disjunctive dependencies.
Models of distributed system protocols are often verified with model checking approaches such as TLA+ [17]. Model checking programs is typically undecidable, making it ill-suited to integrate directly into a programming model in the same manner as a (decidable) type system. To make verification tractable, TLA+ models are often simplified versions of the implementations they represent, potentially leading to discrepancies. FLAQR is designed as a core calculus for a distributed programming model, making direct verification of implementations more feasible.
BFT protocols [6,7] use consensus and replication to protect the integrity and availability of operations on a system’s state. Each instance of a BFT protocol essentially enforces a single availability policy and a single integrity policy. While composing multiple instances is possible, doing so provides no end-to-end availability or integrity guarantees for the system as a whole. FLAQR programs, by constrast, routinely compose consensus and replication primitives to enforce multiple policies while also providing end-to-end system guarantees.
Our blame semantics presented in Section 7.1 has some resemblance to the idea of blame used to detect contract violations [11] and applied to gradual typing [25]. In our system, blame is necessarily ambiguous since perfect fault detection is not possible. Hence, rather than identifying a single program point responsible for a contract or type violation, our semantics builds constraints that specify a set of principals that may be responsible for a given failure.
In [9] Clarkson and Schneider talks about integrity measures such as contamination and suppression. The idea of suppression can be equivalent to the idea of unavailability. Although in [9] suppression happens due to untrusted input making trusted output unavailable. In FLAQR, unavailibity is caused by both unavailable and untrusted (via statement) inputs.
Conclusion
In this work, we extend Flow Limited Authorization Model [3] with availability policies. We introduce a core calculus and type-system, FLAQR, for building decentralized applications that are secure by construction. We identify a trade-off relation between integrity and availability, and introduce two binary operations partial-and and partial-or, specifically to express integrities of quorum based replicated programs. We define relation and judgments that help us reason about a principal’s authority over availability of a type. We introduce blame semantics that associate failures with malicious hosts of a quorum system to ensure that quorums can not exceed a bounded number of failures without causing the whole system to fail. FLAQR ensures end-to-end information security with noninterference for confidentiality, integrity and availability. Finally we present FLAQR, which is an extension of FLAQR with language constructs that support secret sharing between hosts with mutual distrust. We extend our failure propagation rules and blame semantics to assign blame to appropriate principals when a secret sharing round fails.
Footnotes
Acknowledgments
Funding for this work was provided in part by NSF CAREER CNS-1750060 and IARPA HECTOR CW3002436.
References
1.
M.Abadi, Access control in a core calculus of dependency, in: 11th ACM SIGPLAN Int’l Conf. on Functional Programming, ACM, New York, NY, USA, 2006, pp. 263–273. doi:10.1145/1159803.1159839.
2.
O.Arden, A.Gollamudi, E.Cecchetti, S.Chong and A.C.Myers, A calculus for flow-limited authorization, Technical Report, 2021. doi:10.48550/ARXIV.2104.10379.
3.
O.Arden, J.Liu and A.C.Myers, Flow-limited authorization, in: 28th IEEE Computer Security Foundations Symp, CSF, 2015, pp. 569–583.
4.
O.Arden, J.Liu and A.C.Myers, Flow-limited authorization: Technical Report, Technical Report, 1813–40138, Cornell University Computing and Information Science, 2015.
5.
O.Arden and A.C.Myers, A calculus for flow-limited authorization, in: 29th IEEE Computer Security Foundations Symp, CSF, 2016, pp. 135–147.
6.
A.Bessani, J.Sousa and E.E.Alchieri, State machine replication for the masses with BFT-SMaRt, in: Dependable Systems and Networks (DSN), 2014 44th Annual IEEE/IFIP International Conference on, IEEE, 2014, pp. 355–362.
7.
M.Castro and B.Liskov, Practical Byzantine fault tolerance and proactive recovery, ACM Trans. on Computer Systems20 (2002), 2002.
8.
E.Cecchetti, A.C.Myers and O.Arden, Nonmalleable information flow control, in: 24th ACM Conf. on Computer and Communications Security (CCS), 2017, pp. 1875–1891.
9.
M.R.Clarkson and F.B.Schneider, Quantification of integrity, in: Proc. IEEE Computer Security Foundations Symposium, 2010, pp. 28–43.
10.
E.Dawson and D.Donovan, The breadth of Shamir’s secret-sharing scheme, Computer & Security (1994).
11.
R.B.Findler and M.Felleisen, Contracts for higher-order functions, SIGPLAN Not.37(9) (2002), 48–59. doi:10.1145/583852.581484.
12.
J.-Y.Girard, Une extension de L’interpretation de gödel a L’analyse, et son application a L’elimination des coupures dans L’analyse et la theorie des types, in: Studies in Logic and the Foundations of Mathematics, Vol. 63, Elsevier, 1971, pp. 63–92.
13.
J.-Y.Girard, Interpretation fonctionelle et elimination des coupure dans l’arithmetic d’ordre superieur, Ph. D. Thesis, L’universite Paris VII, 1972.
14.
A.Gollamudi, S.Chong and O.Arden, Information flow control for distributed trusted execution environments, in: 32nd IEEE Computer Security Foundations Symp, CSF, 2019.
15.
S.Hunt and D.Sands, A quantale of information, in: 2021 IEEE 34th Computer Security Foundations Symposium (CSF), 2021. doi:10.1109/CSF51468.2021.00031.
16.
L.Lamport, The Part-time Parliament, ACM Trans. on Computer Systems16(2) (1998), 133–169. doi:10.1145/279227.279229.
17.
L.Lamport, The PlusCal algorithm language, in: Theoretical Aspects of Computing – ICTAC 2009, M.Leucker and C.Morgan, eds, Springer, Berlin, Heidelberg, 2009, pp. 36–60. ISBN 978-3-642-03466-4. doi:10.1007/978-3-642-03466-4_2.
18.
J.Liu, O.Arden, M.D.George and A.C.Myers, Fabric: Building open distributed systems securely by construction, J. Computer Security25(4–5) (2017), 319–321. doi:10.3233/JCS-0559.
19.
P.Mondal, M.Algehed and O.Arden, Applying consensus and replication securely with FLAQR, in: IEEE Computer Security Foundations Symp (CSF), 2022, pp. 163–178. doi:10.1109/CSF54842.2022.9919637.
20.
A.C.Myers and B.Liskov, Protecting privacy using the decentralized label model, ACM Transactions on Software Engineering and Methodology9(4) (2000), 410–442. doi:10.1145/363516.363526.
21.
S.Nakamoto, Bitcoin: A peer-to-peer electronic cash system, Consulted1(2012) (2008), 28.
22.
F.Pottier and V.Simonet, Information flow inference for ML, in: 29th ACM Symp. on Principles of Programming Languages (POPL), 2002, pp. 319–330.
23.
J.C.Reynolds, Towards a theory of type structure, in: Programming Symposium, Springer, 1974, pp. 408–425. doi:10.1007/3-540-06859-7_148.
24.
A.Shamir, How to share a secret, Communications of the ACM22(11) (1979), 612–613. doi:10.1145/359168.359176.
25.
P.Wadler and R.B.Findler, Well-typed programs can’t be blamed, in: Programming Languages and Systems, G.Castagna, ed., Springer, Berlin, Heidelberg, 2009, pp. 1–16. ISBN 978-3-642-00590-9.
26.
C.-C.Yang, T.-Y.Chang and M.-S.Hwang, A (t,n) multi-secret sharing scheme, in: Applied Mathematics and Computation, 2004, pp. 483–490.
27.
S.Zdancewic and A.C.Myers, Robust declassification, in: 14th IEEE Computer Security Foundations Workshop (CSFW), 2001, pp. 15–23, ISSN 1063-6900. doi:10.1109/CSFW.2001.930133.
28.
N.Zeldovich, S.Boyd-Wickizer and D.Mazières, Securing distributed systems with information flow control, in: 5th USENIX Symp. on Networked Systems Design and Implementation (NSDI), 2008, pp. 293–308.
29.
L.Zheng and A.C.Myers, End-to-end availability policies and noninterference, in: 18th IEEE Computer Security Foundations Workshop (CSFW), 2005, pp. 272–286. doi:10.1109/CSFW.2005.16.
30.
L.Zheng and A.C.Myers, A language-based approach to secure quorum replication, in: 9th ACM SIGPLAN Workshop on Programming Languages and Analysis for Security (PLAS), 2014.