//////////////////////////////////////////////////////////////////////////////// // Copyright 2019 Google LLC. // // This software is licensed under the terms defined in the Widevine Master // License Agreement. For a copy of this agreement, please contact // widevine-licensing@google.com. //////////////////////////////////////////////////////////////////////////////// // // Description: // Generic elliptic curve classes for private and public keys. Declares // methods for deriving shared session keys and signatures. #ifndef COMMON_EC_KEY_H_ #define COMMON_EC_KEY_H_ #include #include #include "absl/base/macros.h" #include "openssl/ec.h" #include "common/hash_algorithm.h" #include "common/openssl_util.h" namespace widevine { class ECPublicKey; class ECPrivateKey { public: explicit ECPrivateKey(EC_KEY* ec_key); explicit ECPrivateKey(ScopedECKEY ec_key); ECPrivateKey(const ECPrivateKey&); ECPrivateKey() = delete; virtual ~ECPrivateKey() = default; // Accepted standard curves for key generation. Names are derived from SECG. enum EllipticCurve { UNDEFINED_CURVE = 0, SECP256R1, SECP384R1, SECP521R1, }; // Creates an ECPrivateKey using a DER encoded RFC5915 std::string // representing a private key. Returns an ECPrivateKey on success or nullptr // on failure. static std::unique_ptr Create( const std::string& serialized_key); // Exports the matching public key for this private key. virtual std::unique_ptr PublicKey() const; // Calculates a shared session key using ECDH and then uses a key derivation // function, SHA256, to derive a key. // |public_key| is an EC public key with the same curve parameters as key_. It // is used as the public key component of ECDH. // |derived_shared_session_key| will be the result of the derivation. // Caller retains ownership of all pointers. // Returns true on success and false on error. virtual bool DeriveSharedSessionKey( const ECPublicKey& public_key, std::string* derived_shared_session_key) const; // Given a message, calculates a signature using ECDSA with the key_. // |message| is the message to be signed. // |hash_algorithm| specifies the hash algorithm. // |signature| will contain the resulting signature. This will be an ASN.1 // DER-encoded signature. // Caller retains ownership of all pointers. // Returns true on success and false on error. virtual bool GenerateSignature(const std::string& message, HashAlgorithm hash_algorithm, std::string* signature) const; // Returns whether the given private key is the same as key_. virtual bool MatchesPrivateKey(const ECPrivateKey& private_key) const; // Returns whether the given public key is part of the same key pair as key_. virtual bool MatchesPublicKey(const ECPublicKey& public_key) const; // Returns the EllipticCurve associated with key_. virtual EllipticCurve Curve() const; virtual bool SerializedKey(std::string* serialized_key) const; // Gets raw private key bytes. // |raw_private_key| is where the raw bytes are stored. // Returns true on success and false on error. virtual bool GetRawPrivateKey(std::string* raw_private_key) const; private: friend class ECPublicKey; ECPrivateKey& operator=(const ECPrivateKey&) = delete; const EC_KEY* key() const { return key_.get(); } ScopedECKEY key_; }; class ECPublicKey { public: explicit ECPublicKey(EC_KEY* ec_key); explicit ECPublicKey(ScopedECKEY ec_key); ECPublicKey(const ECPublicKey&); virtual ~ECPublicKey() = default; // Creates an ECPublicKey using a DER encoded RFC5208 std::string representing // a public key. Returns an ECPublicKey on success or nullptr on failure. static std::unique_ptr Create(const std::string& serialized_key); // Creates an ECPublicKey from an uncompressed point compatible with X9.62. // Returns an ECPublicKey on success or nullptr on failure. static std::unique_ptr CreateFromKeyPoint( ECPrivateKey::EllipticCurve curve, const std::string& key_point); // Given a message and a signature, verifies that the signature was created // using the private key associated with key_. // |message| is the message that was signed. // |hash_algorithm| specifies the hash algorithm. // |signature| is an ASN.1 DER-encoded signature. // Returns true on success and false on error. virtual bool VerifySignature(const std::string& message, HashAlgorithm hash_algorithm, const std::string& signature) const; // Returns whether the given private key is part of the same key pair as key_. virtual bool MatchesPrivateKey(const ECPrivateKey& private_key) const; // Returns whether the given public key is the same as key_. virtual bool MatchesPublicKey(const ECPublicKey& public_key) const; // Returns the EllipticCurve associated with key_. virtual ECPrivateKey::EllipticCurve Curve() const; virtual bool SerializedKey(std::string* serialized_key) const; // Returns the key in the uncompressed point format. Compatible with X9.62 // The lead byte indicates uncompressed format (0x4). This is followed by the // octets for the X and Y coordinates. virtual bool GetPointEncodedKey(std::string* encoded_key) const; // Gets raw public key bytes. // |raw_public_key| is where the raw bytes are stored. // Returns true on success and false on error. virtual bool GetRawPublicKey(std::string* raw_public_key) const; const EC_KEY* key() const { return key_.get(); } private: ECPublicKey& operator=(const ECPublicKey&) = delete; ScopedECKEY key_; }; } // namespace widevine #endif // COMMON_EC_KEY_H_