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