xref: /aosp_15_r20/external/federated-compute/fcp/secagg/shared/ecdh_key_agreement.h (revision 14675a029014e728ec732f129a32e299b2da0601)
1 /*
2  * Copyright 2018 Google LLC
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef FCP_SECAGG_SHARED_ECDH_KEY_AGREEMENT_H_
18 #define FCP_SECAGG_SHARED_ECDH_KEY_AGREEMENT_H_
19 
20 #include <string>
21 
22 #include "fcp/base/monitoring.h"
23 #include "fcp/secagg/shared/aes_key.h"
24 #include "fcp/secagg/shared/ecdh_keys.h"
25 #include "openssl/base.h"
26 #include "openssl/ec.h"
27 
28 namespace fcp {
29 namespace secagg {
30 
31 // This class represents a participant in the ECDH Key Agreement protocol. It
32 // serves to hold one private/public ECDH key pair, or just one private key
33 // (with no public key associated).
34 //
35 // The curve used for this is NIST P-256, also known as prime256v1.
36 //
37 // The private and public keys can be retrieved from the object in the form of
38 // strings. The compressed representation of the public key is used.
39 //
40 // The shared secret is always hashed with SHA-256 to produce a valid AES-256
41 // key before returning.
42 //
43 // Because only certain strings are valid ECDH keys, even if they have the
44 // correct length, this class uses factory methods to instantiate new objects.
45 // The constructors should never be called directly by a user of this class.
46 class EcdhKeyAgreement {
47  public:
48   // FACTORY METHODS:
49   // Use one of the CreateFrom* factory methods below to instantiate a new
50   // EcdhKeyAgreement object, and note that these methods may fail. Do not use a
51   // constructor directly to instantiate an EcdhKeyAgreement object.
52 
53   // Returns a new EcdhKeyAgreement object containing a keypair randomly
54   // generated using OpenSSL's randomness. Only fails if OpenSSL has an internal
55   // error.
56   static StatusOr<std::unique_ptr<EcdhKeyAgreement>> CreateFromRandomKeys();
57 
58   // Returns a new EcdhKeyAgreement object containing the supplied private key,
59   // and no public key. This object can still be used to do ECDH with other
60   // public keys.
61   // Fails if the supplied private key is invalid.
62   static StatusOr<std::unique_ptr<EcdhKeyAgreement>> CreateFromPrivateKey(
63       const EcdhPrivateKey& private_key);
64 
65   // Returns a new EcdhKeyAgreement object containing the supplied
66   // private/public keypair.
67   // Fails if the supplied keypair is invalid.
68   static StatusOr<std::unique_ptr<EcdhKeyAgreement>> CreateFromKeypair(
69       const EcdhPrivateKey& private_key, const EcdhPublicKey& public_key);
70 
71   // Returns a representation of the private key stored in this object.
72   EcdhPrivateKey PrivateKey() const;
73 
74   // Returns a representation of the public key stored in this object. This uses
75   // the compressed ECDH public key representation.
76   //
77   // If object has no public key (i.e. it was constructed with
78   // CreateFromPrivateKey), this method will return an empty string.
79   EcdhPublicKey PublicKey() const;
80 
81   // Returns the shared secret AES key generated by ECDH, using  with the stored
82   // ECDH private key and the supplied ECDH public key, and then hashed with
83   // SHA-256. The output will be an AES-256 key.
84   //
85   // If the other_key is not a valid public key, instead returns an error status
86   // with code INVALID_ARGUMENT.
87   StatusOr<AesKey> ComputeSharedSecret(const EcdhPublicKey& other_key) const;
88 
89   // DO NOT USE THESE CONSTRUCTORS.
90   // Instead, one of the CreateFrom* factory methods below.
91   // These constructors are made public only as an implementation detail.
92   // See https://abseil.io/tips/134 for details.
93   EcdhKeyAgreement();
94   explicit EcdhKeyAgreement(EC_KEY* key);
95 
96  private:
97   std::unique_ptr<EC_KEY, void (*)(EC_KEY*)> key_;
98 };
99 
100 }  // namespace secagg
101 }  // namespace fcp
102 
103 #endif  // FCP_SECAGG_SHARED_ECDH_KEY_AGREEMENT_H_
104