Files
media_cas_packager_sdk_source/common/ec_key.h
Lu Chen 79e39b482d Add support for Widevine ECM v3
Widevine ECM v3 is redesigned mainly based on protobuf, and supports new features including carrying fingerprinting and service blocking information. Existing clients must upgrade the Widevine CAS plugin to use the new ECM v3.
2020-12-14 09:49:52 -08:00

161 lines
5.7 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// 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 <memory>
#include <string>
#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<ECPrivateKey> Create(
const std::string& serialized_key);
// Exports the matching public key for this private key.
virtual std::unique_ptr<ECPublicKey> 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<ECPublicKey> 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<ECPublicKey> 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;
private:
friend class ECPrivateKey;
ECPublicKey& operator=(const ECPublicKey&) = delete;
const EC_KEY* key() const { return key_.get(); }
ScopedECKEY key_;
};
} // namespace widevine
#endif // COMMON_EC_KEY_H_