Files
android/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h
John W. Bruce d9b90be205 Enable SPOIDs in Treble Widevine Glue Layer
Adds code to the Widevine Glue Layer that drives the generation and use
of SPOIDs on platforms that support SPOIDs. (All devices whose first
release is Android O or later.) Note that this only applies to the new,
Treble-ized API. If the Widevine DRM Plugin is accessed through the old
API, it will not use SPOIDs. This is by design because the old API does
not provide an application package name, so SPOID generation is no
better than the existing, origin-based solution.

Bug: 27101531
Test: Unit tests
Test: GTS tests
Test: Google Play
Change-Id: I80f79fca84065105e218e9070a1d5299c8e33500
2017-03-02 13:46:16 -08:00

378 lines
11 KiB
C++

//
// Copyright 2017 Google Inc. All Rights Reserved.
//
#ifndef WV_DRM_PLUGIN_H_
#define WV_DRM_PLUGIN_H_
#include <map>
#include <android/hardware/drm/1.0/IDrmPlugin.h>
#include <android/hardware/drm/1.0/IDrmPluginListener.h>
#include "cdm_client_property_set.h"
#include "cdm_identifier.h"
#include "OEMCryptoCENC.h"
#include "utils/String8.h"
#include "utils/Vector.h"
#include "wv_cdm_event_listener.h"
#include "wv_content_decryption_module.h"
#include "WVGenericCryptoInterface.h"
#include "WVTypes.h"
namespace wvdrm {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace widevine {
using ::android::hardware::drm::V1_0::EventType;
using ::android::hardware::drm::V1_0::IDrmPlugin;
using ::android::hardware::drm::V1_0::IDrmPluginListener;
using ::android::hardware::drm::V1_0::KeyRequestType;
using ::android::hardware::drm::V1_0::KeyStatus;
using ::android::hardware::drm::V1_0::KeyType;
using ::android::hardware::drm::V1_0::KeyValue;
using ::android::hardware::drm::V1_0::SecureStop;
using ::android::hardware::drm::V1_0::Status;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::sp;
using android::status_t;
using android::String8;
using android::Vector;
using std::map;
using wvcdm::CdmIdentifier;
using wvcdm::CdmKeyStatusMap;
using wvcdm::CdmSessionId;
using wvcdm::CdmResponseType;
using wvcdm::WvContentDecryptionModule;
const OEMCrypto_Algorithm kInvalidCryptoAlgorithm =
static_cast<OEMCrypto_Algorithm>(-1);
struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener,
wvcdm::WvCdmEventListener {
WVDrmPlugin(const sp<WvContentDecryptionModule>& cdm,
const std::string& appPackageName,
WVGenericCryptoInterface* crypto);
virtual ~WVDrmPlugin();
Return<void> openSession(openSession_cb _hidl_cb) override;
Return<Status> closeSession(const hidl_vec<uint8_t>& sessionId) override;
Return<void> getKeyRequest(
const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& initData,
const hidl_string& mimeType,
KeyType keyType,
const hidl_vec<KeyValue>& optionalParameters,
getKeyRequest_cb _hidl_cb) override;
Return<void> provideKeyResponse(
const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& response,
provideKeyResponse_cb _hidl_cb) override;
Return<Status> removeKeys(const hidl_vec<uint8_t>& sessionId) override;
Return<Status> restoreKeys(
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keySetId) override;
Return<void> queryKeyStatus(
const hidl_vec<uint8_t>& sessionId,
queryKeyStatus_cb _hidl_cb) override;
Return<void> getProvisionRequest(
const hidl_string& certificateType,
const hidl_string& certificateAuthority,
getProvisionRequest_cb _hidl_cb) override;
Return<void> provideProvisionResponse(
const hidl_vec<uint8_t>& response,
provideProvisionResponse_cb _hidl_cb) override;
Return<void> getSecureStops(getSecureStops_cb _hidl_cb) override;
Return<void> getSecureStop(
const hidl_vec<uint8_t>& secureStopId,
getSecureStop_cb _hidl_cb) override;
Return<Status> releaseAllSecureStops() override;
Return<Status> releaseSecureStop(
const hidl_vec<uint8_t>& secureStopId) override;
Return<void> getPropertyString(
const hidl_string& propertyName,
getPropertyString_cb _hidl_cb) override;
Return<void> getPropertyByteArray(
const hidl_string& propertyName,
getPropertyByteArray_cb _hidl_cb) override;
Return<Status> setPropertyString(
const hidl_string& propertyName,
const hidl_string& value) override;
Return<Status> setPropertyByteArray(
const hidl_string& propertyName,
const hidl_vec<uint8_t>& value) override;
Return<Status> setCipherAlgorithm(
const hidl_vec<uint8_t>& sessionId,
const hidl_string& algorithm) override;
Return<Status> setMacAlgorithm(
const hidl_vec<uint8_t>& sessionId,
const hidl_string& algorithm) override;
Return<void> encrypt(
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId,
const hidl_vec<uint8_t>& input,
const hidl_vec<uint8_t>& iv,
encrypt_cb _hidl_cb) override;
Return<void> decrypt(
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId,
const hidl_vec<uint8_t>& input,
const hidl_vec<uint8_t>& iv,
decrypt_cb _hidl_cb) override;
Return<void> sign(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
sign_cb _hidl_cb) override;
Return<void> verify(
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId,
const hidl_vec<uint8_t>& message,
const hidl_vec<uint8_t>& signature,
verify_cb _hidl_cb) override;
Return<void> signRSA(
const hidl_vec<uint8_t>& sessionId,
const hidl_string& algorithm,
const hidl_vec<uint8_t>& message,
const hidl_vec<uint8_t>& wrappedkey,
signRSA_cb _hidl_cb) override;
Return<void> setListener(const sp<IDrmPluginListener>& listener) override;
Return<void> sendEvent(
EventType eventType,
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& data) override;
Return<void> sendExpirationUpdate(
const hidl_vec<uint8_t>& sessionId,
int64_t expiryTimeInMS) override;
Return<void> sendKeysChange(
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<KeyStatus>& keyStatusList,
bool hasNewUsableKey) override;
// The following methods do not use hidl interface, it is used internally.
virtual status_t unprovisionDevice();
virtual void OnSessionRenewalNeeded(const CdmSessionId& cdmSessionId);
virtual void OnSessionKeysChange(
const CdmSessionId& cdmSessionId,
const CdmKeyStatusMap& cdmKeysStatus,
bool hasNewUsableKey);
virtual void OnExpirationUpdate(
const CdmSessionId& cdmSessionId,
int64_t newExpiryTimeSeconds);
private:
WVDRM_DISALLOW_COPY_AND_ASSIGN_AND_NEW(WVDrmPlugin);
struct CryptoSession {
public:
CryptoSession()
: mOecSessionId(-1),
mCipherAlgorithm(kInvalidCryptoAlgorithm),
mMacAlgorithm(kInvalidCryptoAlgorithm) {}
CryptoSession(OEMCrypto_SESSION sessionId)
: mOecSessionId(sessionId),
mCipherAlgorithm(kInvalidCryptoAlgorithm),
mMacAlgorithm(kInvalidCryptoAlgorithm) {}
OEMCrypto_SESSION oecSessionId() const { return mOecSessionId; }
OEMCrypto_Algorithm cipherAlgorithm() const { return mCipherAlgorithm; }
void setCipherAlgorithm(OEMCrypto_Algorithm newAlgorithm) {
mCipherAlgorithm = newAlgorithm;
}
OEMCrypto_Algorithm macAlgorithm() const { return mMacAlgorithm; }
void setMacAlgorithm(OEMCrypto_Algorithm newAlgorithm) {
mMacAlgorithm = newAlgorithm;
}
private:
OEMCrypto_SESSION mOecSessionId;
OEMCrypto_Algorithm mCipherAlgorithm;
OEMCrypto_Algorithm mMacAlgorithm;
};
class WVClientPropertySet : public wvcdm::CdmClientPropertySet {
public:
WVClientPropertySet()
: mUsePrivacyMode(false), mShareKeys(false), mSessionSharingId(0) {}
virtual ~WVClientPropertySet() {}
virtual const std::string& security_level() const {
return mSecurityLevel;
}
void set_security_level(const std::string& securityLevel) {
mSecurityLevel = securityLevel;
}
virtual bool use_privacy_mode() const {
return mUsePrivacyMode;
}
void set_use_privacy_mode(bool usePrivacyMode) {
mUsePrivacyMode = usePrivacyMode;
}
virtual const std::string& service_certificate() const {
return mServiceCertificate;
}
virtual void set_service_certificate(
const std::string& serviceCertificate) {
mServiceCertificate = serviceCertificate;
}
virtual const std::string& device_provisioning_service_certificate() const {
// Android does not support service certificates for provisioning.
return mEmptyString;
}
virtual void set_device_provisioning_service_certificate(
const std::string& ) {
// Ignore. Android does not support service certificates for provisioning
}
virtual bool is_session_sharing_enabled() const {
return mShareKeys;
}
void set_is_session_sharing_enabled(bool shareKeys) {
mShareKeys = shareKeys;
}
virtual uint32_t session_sharing_id() const {
return mSessionSharingId;
}
virtual void set_session_sharing_id(uint32_t id) {
mSessionSharingId = id;
}
virtual const std::string& app_id() const {
return mAppId;
}
void set_app_id(const std::string& appId) {
mAppId = appId;
}
private:
DISALLOW_EVIL_CONSTRUCTORS(WVClientPropertySet);
std::string mSecurityLevel;
bool mUsePrivacyMode;
std::string mServiceCertificate;
bool mShareKeys;
uint32_t mSessionSharingId;
std::string mAppId;
const std::string mEmptyString;
} mPropertySet;
class CdmIdentifierBuilder {
public:
CdmIdentifierBuilder();
const CdmIdentifier& get_identifier();
const std::string& get_device_unique_id();
bool set_device_id(const std::string& id);
const std::string& app_package_name() { return mAppPackageName; }
bool set_app_package_name(const std::string& id);
const std::string& origin() const { return mCdmIdentifier.origin; }
bool set_origin(const std::string& id);
private:
WVDRM_DISALLOW_COPY_AND_ASSIGN(CdmIdentifierBuilder);
CdmIdentifier mCdmIdentifier;
bool mIsIdentifierSealed;
bool mUseSpoid;
std::string mDeviceId;
std::string mAppPackageName;
void calculateSpoid();
} mCdmIdentifierBuilder;
sp<wvcdm::WvContentDecryptionModule> const mCDM;
WVGenericCryptoInterface* mCrypto;
map<CdmSessionId, CryptoSession> mCryptoSessions;
sp<IDrmPluginListener> mListener;
status_t queryProperty(const std::string& property,
std::string& stringValue) const;
status_t queryProperty(wvcdm::SecurityLevel securityLevel,
const std::string& property,
std::string& stringValue) const;
status_t queryProperty(const std::string& property,
String8& string8_value) const;
status_t queryProperty(const std::string& property,
Vector<uint8_t>& vector_value) const;
status_t mapAndNotifyOfCdmResponseType(const Vector<uint8_t>& sessionId,
CdmResponseType res);
status_t mapAndNotifyOfOEMCryptoResult(const Vector<uint8_t>& sessionId,
OEMCryptoResult res);
status_t mapOEMCryptoResult(OEMCryptoResult res);
bool initDataResemblesPSSH(const Vector<uint8_t>& initData);
status_t unprovision(const CdmIdentifier& identifier);
};
} // namespace widevine
} // namespace V1_0
} // namespace drm
} // namespace hardware
} // namespace wvdrm
#endif // WV_DRM_PLUGIN_H_