1*14675a02SAndroid Build Coastguard Worker /* 2*14675a02SAndroid Build Coastguard Worker * Copyright 2018 Google LLC 3*14675a02SAndroid Build Coastguard Worker * 4*14675a02SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*14675a02SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*14675a02SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*14675a02SAndroid Build Coastguard Worker * 8*14675a02SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*14675a02SAndroid Build Coastguard Worker * 10*14675a02SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*14675a02SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*14675a02SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*14675a02SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*14675a02SAndroid Build Coastguard Worker * limitations under the License. 15*14675a02SAndroid Build Coastguard Worker */ 16*14675a02SAndroid Build Coastguard Worker 17*14675a02SAndroid Build Coastguard Worker #ifndef FCP_SECAGG_CLIENT_SECAGG_CLIENT_H_ 18*14675a02SAndroid Build Coastguard Worker #define FCP_SECAGG_CLIENT_SECAGG_CLIENT_H_ 19*14675a02SAndroid Build Coastguard Worker 20*14675a02SAndroid Build Coastguard Worker #include <memory> 21*14675a02SAndroid Build Coastguard Worker #include <string> 22*14675a02SAndroid Build Coastguard Worker #include <vector> 23*14675a02SAndroid Build Coastguard Worker 24*14675a02SAndroid Build Coastguard Worker #include "absl/synchronization/mutex.h" 25*14675a02SAndroid Build Coastguard Worker #include "fcp/base/monitoring.h" 26*14675a02SAndroid Build Coastguard Worker #include "fcp/secagg/client/secagg_client_state.h" 27*14675a02SAndroid Build Coastguard Worker #include "fcp/secagg/client/send_to_server_interface.h" 28*14675a02SAndroid Build Coastguard Worker #include "fcp/secagg/client/state_transition_listener_interface.h" 29*14675a02SAndroid Build Coastguard Worker #include "fcp/secagg/shared/aes_prng_factory.h" 30*14675a02SAndroid Build Coastguard Worker #include "fcp/secagg/shared/async_abort.h" 31*14675a02SAndroid Build Coastguard Worker #include "fcp/secagg/shared/input_vector_specification.h" 32*14675a02SAndroid Build Coastguard Worker #include "fcp/secagg/shared/prng.h" 33*14675a02SAndroid Build Coastguard Worker #include "fcp/secagg/shared/secagg_messages.pb.h" 34*14675a02SAndroid Build Coastguard Worker #include "fcp/secagg/shared/secagg_vector.h" 35*14675a02SAndroid Build Coastguard Worker 36*14675a02SAndroid Build Coastguard Worker namespace fcp { 37*14675a02SAndroid Build Coastguard Worker namespace secagg { 38*14675a02SAndroid Build Coastguard Worker 39*14675a02SAndroid Build Coastguard Worker // Represents a client for the secure aggregation protocol. Each instance of 40*14675a02SAndroid Build Coastguard Worker // this class performs just *one* session of the protocol. 41*14675a02SAndroid Build Coastguard Worker // 42*14675a02SAndroid Build Coastguard Worker // To create a new instance, use the public constructor. The Start method can be 43*14675a02SAndroid Build Coastguard Worker // used to produce the first message of the protocol, the SetInput method sets 44*14675a02SAndroid Build Coastguard Worker // the input for this client and the ReceiveMessage method is used to process 45*14675a02SAndroid Build Coastguard Worker // incoming messages from the server. 46*14675a02SAndroid Build Coastguard Worker // 47*14675a02SAndroid Build Coastguard Worker // The class is thread-safe, but will deadlock if accessed reentrantly from 48*14675a02SAndroid Build Coastguard Worker // the SendToServerInterface callback. 49*14675a02SAndroid Build Coastguard Worker // 50*14675a02SAndroid Build Coastguard Worker // Functions are marked virtual for mockability. Additional virtual attributes 51*14675a02SAndroid Build Coastguard Worker // should be added as needed by tests. 52*14675a02SAndroid Build Coastguard Worker 53*14675a02SAndroid Build Coastguard Worker class SecAggClient { 54*14675a02SAndroid Build Coastguard Worker public: 55*14675a02SAndroid Build Coastguard Worker // Creates a new instance of the client. 56*14675a02SAndroid Build Coastguard Worker // 57*14675a02SAndroid Build Coastguard Worker // max_neighbors_expected is the upper bound on the total number of neighbors 58*14675a02SAndroid Build Coastguard Worker // this client may interact with. If the server tries to start a protocol 59*14675a02SAndroid Build Coastguard Worker // session with more than this many neighbors, this client will abort. 60*14675a02SAndroid Build Coastguard Worker // 61*14675a02SAndroid Build Coastguard Worker // minimum_surviving_neighbors_for_reconstruction is the threshold lower bound 62*14675a02SAndroid Build Coastguard Worker // on the number of neighbors participating. If there are ever fewer than this 63*14675a02SAndroid Build Coastguard Worker // number of remaining neighbors in the protocol, this client will abort. 64*14675a02SAndroid Build Coastguard Worker // 65*14675a02SAndroid Build Coastguard Worker // input_vector_specs must contain one InputVectorSpecification for each input 66*14675a02SAndroid Build Coastguard Worker // vector which the protocol will aggregate. This may optionally be moved 67*14675a02SAndroid Build Coastguard Worker // from using std::move(caller_input_vector_specs). 68*14675a02SAndroid Build Coastguard Worker // 69*14675a02SAndroid Build Coastguard Worker // prng should always be an instance of CryptoRandPrng, except as needed for 70*14675a02SAndroid Build Coastguard Worker // testing purposes. The client will consume prng, taking ownership of it. 71*14675a02SAndroid Build Coastguard Worker // 72*14675a02SAndroid Build Coastguard Worker // sender is used by the client to send messages to the server. The client 73*14675a02SAndroid Build Coastguard Worker // will consume sender, taking ownership of it. 74*14675a02SAndroid Build Coastguard Worker // 75*14675a02SAndroid Build Coastguard Worker // transition_listener is used to trigger state transition events, used for 76*14675a02SAndroid Build Coastguard Worker // logging. 77*14675a02SAndroid Build Coastguard Worker // 78*14675a02SAndroid Build Coastguard Worker // prng_factory is a pointer to an instance of a subclass of AesPrngFactory. 79*14675a02SAndroid Build Coastguard Worker // The type of prng_factory must be consistent with the one used on the 80*14675a02SAndroid Build Coastguard Worker // server. 81*14675a02SAndroid Build Coastguard Worker // 82*14675a02SAndroid Build Coastguard Worker // async_abort_for_test, optionally, allows the caller to reset the abort 83*14675a02SAndroid Build Coastguard Worker // signal. This is used to exhaustively test all abort paths, and should not 84*14675a02SAndroid Build Coastguard Worker // be used in production; specifically, if this paramter is not nullptr, 85*14675a02SAndroid Build Coastguard Worker // Abort() will no longer abort a state-in-progress; it will only abort across 86*14675a02SAndroid Build Coastguard Worker // state transitions. 87*14675a02SAndroid Build Coastguard Worker SecAggClient( 88*14675a02SAndroid Build Coastguard Worker int max_neighbors_expected, 89*14675a02SAndroid Build Coastguard Worker int minimum_surviving_neighbors_for_reconstruction, 90*14675a02SAndroid Build Coastguard Worker std::vector<InputVectorSpecification> input_vector_specs, 91*14675a02SAndroid Build Coastguard Worker std::unique_ptr<SecurePrng> prng, 92*14675a02SAndroid Build Coastguard Worker std::unique_ptr<SendToServerInterface> sender, 93*14675a02SAndroid Build Coastguard Worker std::unique_ptr<StateTransitionListenerInterface> transition_listener, 94*14675a02SAndroid Build Coastguard Worker std::unique_ptr<AesPrngFactory> prng_factory, 95*14675a02SAndroid Build Coastguard Worker std::atomic<std::string*>* abort_signal_for_test = nullptr); 96*14675a02SAndroid Build Coastguard Worker virtual ~SecAggClient() = default; 97*14675a02SAndroid Build Coastguard Worker 98*14675a02SAndroid Build Coastguard Worker // Disallow copy and move. 99*14675a02SAndroid Build Coastguard Worker SecAggClient(const SecAggClient&) = delete; 100*14675a02SAndroid Build Coastguard Worker SecAggClient& operator=(const SecAggClient&) = delete; 101*14675a02SAndroid Build Coastguard Worker 102*14675a02SAndroid Build Coastguard Worker // Initiates the protocol by computing its first message and sending it to 103*14675a02SAndroid Build Coastguard Worker // the server. This method should only be called once. The output will be OK 104*14675a02SAndroid Build Coastguard Worker // unless it is called more than once. 105*14675a02SAndroid Build Coastguard Worker virtual Status Start(); 106*14675a02SAndroid Build Coastguard Worker 107*14675a02SAndroid Build Coastguard Worker // Makes this client abort the protocol and sends a message to notify the 108*14675a02SAndroid Build Coastguard Worker // server. All the state is erased. A new instance of SecAggClient will have 109*14675a02SAndroid Build Coastguard Worker // to be created to restart the protocol. 110*14675a02SAndroid Build Coastguard Worker // 111*14675a02SAndroid Build Coastguard Worker // The status will be OK unless the protocol was already completed or aborted. 112*14675a02SAndroid Build Coastguard Worker Status Abort(); 113*14675a02SAndroid Build Coastguard Worker 114*14675a02SAndroid Build Coastguard Worker // Makes this client abort the protocol and sends a message to notify the 115*14675a02SAndroid Build Coastguard Worker // server. All the state is erased. A new instance of SecAggClient will have 116*14675a02SAndroid Build Coastguard Worker // to be created to restart the protocol. 117*14675a02SAndroid Build Coastguard Worker // 118*14675a02SAndroid Build Coastguard Worker // The specified reason for aborting will be sent to the server and logged. 119*14675a02SAndroid Build Coastguard Worker // 120*14675a02SAndroid Build Coastguard Worker // The status will be OK unless the protocol was already completed or aborted. 121*14675a02SAndroid Build Coastguard Worker Status Abort(const std::string& reason); 122*14675a02SAndroid Build Coastguard Worker 123*14675a02SAndroid Build Coastguard Worker // Sets the input of this client for this protocol session. This method should 124*14675a02SAndroid Build Coastguard Worker // only be called once. 125*14675a02SAndroid Build Coastguard Worker // 126*14675a02SAndroid Build Coastguard Worker // If the input does not match the format laid out in input_vector_specs, 127*14675a02SAndroid Build Coastguard Worker // this will return INVALID_ARGUMENT. If SetInput has already been called or 128*14675a02SAndroid Build Coastguard Worker // if the client is in an aborted or completed state, this will return 129*14675a02SAndroid Build Coastguard Worker // FAILED_PRECONDITION. Otherwise returns OK. 130*14675a02SAndroid Build Coastguard Worker Status SetInput(std::unique_ptr<SecAggVectorMap> input_map); 131*14675a02SAndroid Build Coastguard Worker 132*14675a02SAndroid Build Coastguard Worker // Returns a string uniquely describing the current state of the client's FSM. 133*14675a02SAndroid Build Coastguard Worker ABSL_MUST_USE_RESULT std::string State() const; 134*14675a02SAndroid Build Coastguard Worker 135*14675a02SAndroid Build Coastguard Worker // Returns true if the client has aborted the protocol, false else. 136*14675a02SAndroid Build Coastguard Worker ABSL_MUST_USE_RESULT bool IsAborted() const; 137*14675a02SAndroid Build Coastguard Worker 138*14675a02SAndroid Build Coastguard Worker // Returns true if the client has successfully completed the protocol, 139*14675a02SAndroid Build Coastguard Worker // false else. 140*14675a02SAndroid Build Coastguard Worker ABSL_MUST_USE_RESULT bool IsCompletedSuccessfully() const; 141*14675a02SAndroid Build Coastguard Worker 142*14675a02SAndroid Build Coastguard Worker // Returns a string describing the reason that the client aborted. 143*14675a02SAndroid Build Coastguard Worker // If the client has not actually aborted, returns an error Status with code 144*14675a02SAndroid Build Coastguard Worker // PRECONDITION_FAILED. 145*14675a02SAndroid Build Coastguard Worker ABSL_MUST_USE_RESULT StatusOr<std::string> ErrorMessage() const; 146*14675a02SAndroid Build Coastguard Worker 147*14675a02SAndroid Build Coastguard Worker // Used to process an incoming message from the server. This method uses the 148*14675a02SAndroid Build Coastguard Worker // SendToServerInterface passed to the constructor to send the response 149*14675a02SAndroid Build Coastguard Worker // directly to the server. 150*14675a02SAndroid Build Coastguard Worker // 151*14675a02SAndroid Build Coastguard Worker // The output will be true if the client is still active, or false if the 152*14675a02SAndroid Build Coastguard Worker // client is now in a terminal state. The output will be a failure status if 153*14675a02SAndroid Build Coastguard Worker // the client did not process the message because it was in a terminal state, 154*14675a02SAndroid Build Coastguard Worker // or because the message was the wrong type. 155*14675a02SAndroid Build Coastguard Worker StatusOr<bool> ReceiveMessage(const ServerToClientWrapperMessage& incoming); 156*14675a02SAndroid Build Coastguard Worker 157*14675a02SAndroid Build Coastguard Worker private: 158*14675a02SAndroid Build Coastguard Worker mutable absl::Mutex mu_; 159*14675a02SAndroid Build Coastguard Worker 160*14675a02SAndroid Build Coastguard Worker std::atomic<std::string*> abort_signal_; 161*14675a02SAndroid Build Coastguard Worker AsyncAbort async_abort_; 162*14675a02SAndroid Build Coastguard Worker 163*14675a02SAndroid Build Coastguard Worker // The internal State object, containing details about this client's current 164*14675a02SAndroid Build Coastguard Worker // state. 165*14675a02SAndroid Build Coastguard Worker std::unique_ptr<SecAggClientState> state_ ABSL_GUARDED_BY(mu_); 166*14675a02SAndroid Build Coastguard Worker }; 167*14675a02SAndroid Build Coastguard Worker 168*14675a02SAndroid Build Coastguard Worker } // namespace secagg 169*14675a02SAndroid Build Coastguard Worker } // namespace fcp 170*14675a02SAndroid Build Coastguard Worker 171*14675a02SAndroid Build Coastguard Worker #endif // FCP_SECAGG_CLIENT_SECAGG_CLIENT_H_ 172