Merges to android Pi release (part 10)

These are a set of CLs merged from the wv cdm repo to the android repo.

* Level3 cleanup for SHA + field provision headers

  Author: Srujan Gaddam <srujzs@google.com>

  [ Merge of http://go/wvgerrit/37581 ]

  Moved some redundant macro and struct definitions out of hmac.cpp and
  sha.cpp into a separate header file to make the build easier and
  cleaner. Also cleaned up unnecessary includes and method signatures
  in field_provision.h.

* Address CDM_All_Tests failures

  Author: Rahul Frias <rfrias@google.com>

  [ Merge of http://go/wvgerrit/37580 ]

  CDM engine tests for CE CDM occasionally fails when CDM_All_Tests
  is run by the build server. The failures are due to a nonce generation
  error. If provisioning fails due to a nonce generation error, a delay
  followed by a retry will be attempted.

* Update OEMCrypto version to 13 in cdm.gyp

  Author: Gene Morgan <gmorgan@google.com>

  [ Merge of http://go/wvgerrit/37520 ]

* Use per-session service certificates for licensing

  Author: Rahul Frias <rfrias@google.com>

  [ Merge of http://go/wvgerrit/37260 ]

  These changes allow for service certificates to be specified on a
  per-session basis rather than use one common to a CdmEngine instance.

  This also allows for a service certificate request and response handling
  when allowed on the platform, when privacy mode is enabled and a service
  certificate is not provided.

  Request license tests accept a service certificate command line
  parameter in hex (ascii). Earlier it expected it in binary.

  Bug: 68328352

* Refactor service certificate parsing

  Author: Rahul Frias <rfrias@google.com>

  [ Merge of http://go/wvgerrit/37060 ]

  Service certificates may still be set in CdmEngine but service
  certificate requests and responses have been moved from CdmEngine
  to ServiceCertificate. This allows them to be called from lower
  in the heirarchy (a class that CdmEngine depends on).

  Bug: 68328352

* Revert "C++11: Replace OVERRIDE def with override keyword"

  Author: Gene Morgan <gmorgan@google.com>

  [ Merge of http://go/wvgerrit/37020 ]

  This reverts commit 2d3fb5c4c8f4cf5c986ee43723914a23cf76e8f0.

* Modified scripts/makefiles for L3 build

  Author: Srujan Gaddam <srujzs@google.com>

  [ Merge of http://go/wvgerrit/37220 ]

  Changed build-android-haystack.sh and make_fastball_libwvlevel3.sh
  to build using the new liboemcrypto.cpp file. Also changed
  makefiles to build using the new file. Renamed liboemcrypto.cc to
  liboemcrypto.cpp to make it consistent across android and CE CDM. Added
  static libraries that were rebuilt using this change.

* Added android implementations for Level3

  Author: Srujan Gaddam <srujzs@google.com>

  [ Merge of http://go/wvgerrit/37181 ]

  Moved getUniqueID and added Level3FileSystem implementations for
  android. Also deleted redundant and unnecessary methods from
  anroid_keybox.cpp.

* Refactored getUniqueID and updated libl3oemcrypto.cc

  Author: Srujan Gaddam <srujzs@google.com>

  [ Merge of http://go/wvgerrit/37160 ]

  Renamed getUniqueID header and added comments to make it clear what the
  function is doing. Also removed obfuscation of the method name since it
  is implemented by the partner. Updated the libl3oemcrypto.cc file to
  reflect the change as well as be obfuscated.

* Moved clear_cache function out of entry_points

  Author: Srujan Gaddam <srujzs@google.com>

  [ Merge of http://go/wvgerrit/37040 ]

  clear_cache function is unobfuscated and relies on compiler flags to
  work properly, and therefore should be removed from the
  libl3oemcrypto.cpp file and linked during the final build.

* Minor gyp changes and added L3 build file

  Author: Srujan Gaddam <srujzs@google.com>

  [ Merge of http://go/wvgerrit/36480 ]

  Gyp changes to cdm_unittests.gyp to make the test Level3FileSystem build
  only on a level3 build and to oec_level3.gyp to be compatible with the
  changes to the x86-64 platform settings changes (and to use -Wno-unused
  to catch all unused warnings the libl3oemcrypto.cc might cause). This
  change also includes an x86-64 libl3oemcrypto.cc so a Level3 OEMCrypto can build.

* Merge CE & Linux file system/factory + dynamic adapter changes

  Author: Srujan Gaddam <srujzs@google.com>

  [ Merge of http://go/wvgerrit/36220 ]

  This CL merges the changes from
  I27f5037e4fcea94abd84181f55053843b68f3e8d - it adds the CE
  implementation for the file system, as well as the factory methods
  needed to build the file system (and their implementations for both CE
  and linux). As part of the merge, since the Linux build relies on the
  dynamic adapter, that was fixed and gyp changes were made to reflect the
  change.

* Cherry pick change to retrieve/save provisioning cert

  Author: Srujan Gaddam <srujzs@google.com>

  [ Merge of http://go/wvgerrit/30000 ]

  This is cherry pick from level3-dev-3.3 of a merge of
  I4f5dc5c216fa916e0bca0631c4ceda68859baf1d to save the
  certificate for future tests with the current test host setup.

* Merged changes of usage/linux impl of L3FileSystem

  Author: Srujan Gaddam <srujzs@google.com>

  [ Merge of http://go/wvgerrit/35541 ]

  This is a merge of change I15d38b3c36933d061d168e0ec30bcefd0182f32d. It
  also adds a similar change in usage of L3FileSystem write for a line in
  usage_table.cpp.

* Add cdm build changes for new Level3 build

  Author: Srujan Gaddam <srujzs@google.com>

  [ Merge of http://go/wvgerrit/34600 ]

  Original CL: Ib611cf8a8589afa5cd25d6dc5b0aa43922cfda1e

  Adds level3 oemcrypto library for static adapter. Includes changes to
  gyp files to choose between oemcrypto libraries. Also includes changes
  to the dynamic adapter, level3 headers, and entry_points to be
  compatible with the function signature differences when using the
  static adapter.

* Merge OEMCrypto Level3FileSystem interface

  Author: Srujan Gaddam <srujzs@google.com>

  [ Merge of http://go/wvgerrit/34541 ]

  This merges in the interface for the Level3FileSystem object from
  level3_dev_3.3 as well as the linux implementation. Furthermore, this
  merge includes changes in properties and gyp files to allow compilation.
  The associated changes are I3f1c58f0e3782de0669a96725a38673a26cc1a49,
  I9fb2d10b0f966896bea685166c6b6b2e33c995dd, and
  I4c87a5412a8a022fa9cfba43f33bd4d683e61536.

* Merged misc. changes to Level3 files

  Author: Srujan Gaddam <srujzs@google.com>

  [ Merge of http://go/wvgerrit/33303 ]

  Continuation of I03d3aa1a308f2f010dcb6f5e15f927e81e42925b. These changes
  are miscellaneous changes from level3-dev-3.3 involving include
  statements, Caligo compatibility, and new Level3 signatures from changes
  Ibc5befd492b295970e839f3481e2b512b52dcb08 and
  If599e62c72b5eb40c53633cd72a4d20dc859ee52.

* Merged change involving getUniqueId()

  Author: Srujan Gaddam <srujzs@google.com>

  [ Merge of http://go/wvgerrit/33302 ]

  This is a merge from level3-dev-3.3. This change
  (Ibc5befd492b295970e839f3481e2b512b52dcb08) involves
  separating out the method getUniqueId() from the linux_ and
  android_keybox.cpp. This was done so that clients can
  supply the necessary implementation for the method.

* Merged needle file changes from level3-dev-3.3

  Author: Srujan Gaddam <srujzs@google.com>

  [ Merge of http://go/wvgerrit/33301 ]

  Continuation of I3dbf34bab526945720280f819dd3212ae982d2f7. These are
  changes (Ibc5befd492b295970e839f3481e2b512b52dcb08) involving the
  compiled needles for Haystack. Major changes include function signature
  changes, adding non-state needles automatically, and include statements.

* Merged keybox/usage table access and function sigs

  Author: Srujan Gaddam <srujzs@google.com>

  [ Merge of http://go/wvgerrit/33300 ]

  These are changes from level3-dev-3.3. They involve changing function
  signatures/include files for the new Haystack runtime
  (Ibc5befd492b295970e839f3481e2b512b52dcb08). They are also
  related to change I0285e6d85e80b06b7df1ed298cd1145a6c9c4842. Keybox and
  usage table file names are replaced with constant needles. Furthermore,
  a state needle was added that removes the OldUsageTable file. In
  addition, this CL includes removals of method references that are now
  stale due to the introduction of change
  I9fb2d10b0f966896bea685166c6b6b2e33c995dd.

* Android unit test build fixes

  Author: Srujan Gaddam <srujzs@google.com>

  [ Merge of http://go/wvgerrit/37380 ]

  Removed crypto_session_unittest from build script (introduced
  in http://go/wvgerrit/32824), since crypto_session.cpp requires
  some changes to be merged over from oc-mr1-dev (b/64456400).
  Added oemcrypto_session_tests_helper.cpp to the oemcrypto test
  makefile so the oemcrypto unit tests can link in the
  methods from the refactor in http://go/wvgerrit/36562.

BUG: 71650075
Test: Not currently passing. Will be addressed in a subsequent
  commit in the chain.

Change-Id: I7e45901a151e51da96d192d359edddc5fe74946e
This commit is contained in:
Rahul Frias
2018-01-10 18:44:27 -08:00
parent 81d607c008
commit 8b416ae165
25 changed files with 323 additions and 301 deletions

View File

@@ -82,7 +82,6 @@ try_adb_push cdm_feature_test
try_adb_push cdm_extended_duration_test
try_adb_push cdm_session_unittest
try_adb_push counter_metric_unittest
try_adb_push crypto_session_unittest
try_adb_push device_files_unittest
try_adb_push distribution_unittest
try_adb_push event_metric_unittest

View File

@@ -4,6 +4,8 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS := -DDYNAMIC_ADAPTER
LOCAL_C_INCLUDES := \
vendor/widevine/libwvdrmengine/cdm/core/include \
vendor/widevine/libwvdrmengine/cdm/metrics/include \

View File

@@ -49,17 +49,6 @@ class CdmEngine {
// Report whether the service certificate has been set.
virtual bool HasServiceCertificate();
// Generate and return a Service Certificate Request message.
// This message can be sent to the License Server to get a service
// certificate.
virtual bool GetServiceCertificateRequest(CdmKeyMessage* request);
// Parse the message returned by the License Server in response to a
// Service Certificate Request message. Return the service certificate
// from the parsed response.
virtual CdmResponseType ParseServiceCertificateResponse(
const std::string& response, std::string* certificate);
// Session related methods
virtual CdmResponseType OpenSession(
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,

View File

@@ -52,8 +52,7 @@ class CdmSession {
// |forced_session_id| is caller owned and may be null.
// |event_listener| is caller owned, may be null, but must be in scope
// as long as the session is in scope.
virtual CdmResponseType Init(ServiceCertificate* service_certificate,
CdmClientPropertySet* cdm_client_property_set,
virtual CdmResponseType Init(CdmClientPropertySet* cdm_client_property_set,
const CdmSessionId* forced_session_id,
WvCdmEventListener* event_listener);

View File

@@ -8,6 +8,7 @@
#include "initialization_data.h"
#include "license_protocol.pb.h"
#include "scoped_ptr.h"
#include "service_certificate.h"
#include "wv_cdm_types.h"
namespace video_widevine {
@@ -20,7 +21,6 @@ namespace wvcdm {
class Clock;
class CryptoSession;
class PolicyEngine;
class ServiceCertificate;
class CdmSession;
class CryptoKey;
@@ -30,9 +30,10 @@ class CdmLicense {
virtual ~CdmLicense();
virtual bool Init(
ServiceCertificate* service_certificate, const std::string& client_token,
CdmClientTokenType client_token_type, const std::string& device_id,
CryptoSession* session, PolicyEngine* policy_engine);
const std::string& client_token, CdmClientTokenType client_token_type,
const std::string& device_id, bool use_privacy_mode,
const std::string& signed_service_certificate, CryptoSession* session,
PolicyEngine* policy_engine);
virtual CdmResponseType PrepareKeyRequest(
const InitializationData& init_data, CdmLicenseType license_type,
@@ -56,6 +57,7 @@ class CdmLicense {
int64_t grace_period_end_time, CdmSession* cdm_session);
virtual bool RestoreLicenseForRelease(const CdmKeyMessage& license_request,
const CdmKeyResponse& license_response);
virtual bool HasInitData() { return stored_init_data_.get(); }
virtual bool IsKeyLoaded(const KeyId& key_id);
virtual std::string provider_session_token() {
@@ -98,14 +100,16 @@ class CdmLicense {
CdmClientTokenType client_token_type_;
std::string device_id_;
const CdmSessionId session_id_;
scoped_ptr<InitializationData> stored_init_data_;
bool initialized_;
std::set<KeyId> loaded_keys_;
std::string provider_session_token_;
bool renew_with_client_id_;
bool is_offline_;
// Used to encrypt ClientIdentification message
ServiceCertificate* service_certificate_;
// Associated with ClientIdentification encryption
bool use_privacy_mode_;
ServiceCertificate service_certificate_;
// Used for certificate based licensing
CdmKeyMessage key_request_;

View File

@@ -12,7 +12,7 @@
#include "wv_cdm_types.h"
#if defined(UNIT_TEST)
# include <gtest/gtest_prod.h>
#include <gtest/gtest_prod.h>
#endif
namespace wvcdm {

View File

@@ -38,13 +38,6 @@ class ServiceCertificate {
virtual CdmResponseType VerifySignedMessage(const std::string& message,
const std::string& signature);
// Encrypt data using RSA with OAEP padding.
// |plaintext| is the data to be encrypted. |ciphertext| is a pointer to a
// string to contain the decrypted data on return, and may not be null.
// returns NO_ERROR if successful or an appropriate error code otherwise.
virtual CdmResponseType EncryptRsaOaep(const std::string& plaintext,
std::string* ciphertext);
// Encrypt the ClientIdentification message for a provisioning or
// licensing request. Encryption is performed using the current
// service certificate. Return a failure if the service certificate is
@@ -56,8 +49,19 @@ class ServiceCertificate {
const video_widevine::ClientIdentification* clear_client_id,
video_widevine::EncryptedClientIdentification* encrypted_client_id);
// Helper methods
static bool GetRequest(CdmKeyMessage* request);
static CdmResponseType ParseResponse(const std::string& response,
std::string* signed_certificate);
private:
// Encrypt data using RSA with OAEP padding.
// |plaintext| is the data to be encrypted. |ciphertext| is a pointer to a
// string to contain the decrypted data on return, and may not be null.
// returns NO_ERROR if successful or an appropriate error code otherwise.
virtual CdmResponseType EncryptRsaOaep(const std::string& plaintext,
std::string* ciphertext);
// Track whether object holds valid certificate
bool has_certificate_;

View File

@@ -196,8 +196,7 @@ enum CdmResponseType {
UNUSED_2, /* previously INVALID_PARAMETERS_LIC_5 */
INVALID_PARAMETERS_LIC_6,
INVALID_PARAMETERS_LIC_7, /* 155 */
UNUSED_9,
/* UNUSED_9 previously LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR */
LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR,
CENC_INIT_DATA_UNAVAILABLE,
PREPARE_CENC_CONTENT_ID_FAILED,
WEBM_INIT_DATA_UNAVAILABLE,

View File

@@ -14,7 +14,6 @@
#include "clock.h"
#include "device_files.h"
#include "file_store.h"
#include "license_protocol.pb.h"
#include "log.h"
#include "properties.h"
#include "string_conversions.h"
@@ -29,9 +28,6 @@ const size_t kUsageReportsPerRequest = 1;
namespace wvcdm {
using video_widevine::SignedMessage;
using video_widevine::LicenseError;
class UsagePropertySet : public CdmClientPropertySet {
public:
UsagePropertySet() {}
@@ -99,66 +95,6 @@ bool CdmEngine::HasServiceCertificate() {
return service_certificate_.has_certificate();
}
bool CdmEngine::GetServiceCertificateRequest(CdmKeyMessage* request) {
if (!request) {
LOGE("ServiceCertificate::PrepareRequest: no request parameter provided");
return false;
}
SignedMessage message;
message.set_type(SignedMessage::SERVICE_CERTIFICATE_REQUEST);
message.SerializeToString(request);
return true;
}
CdmResponseType CdmEngine::ParseServiceCertificateResponse(
const std::string& response, std::string* certificate) {
if (response.empty()) {
LOGE("CdmEngine::ParseServiceCertificateResponse: empty response");
return EMPTY_RESPONSE_ERROR_1;
}
if (!certificate) {
LOGE("CdmEngine::ParseServiceCertificateResponse: null return parameter");
return INVALID_PARAMETERS_ENG_24;
}
SignedMessage signed_response;
if (!signed_response.ParseFromString(response)) {
LOGE(
"CdmEngine::ParseServiceCertificateResponse: cannot parse response");
return PARSE_RESPONSE_ERROR_1;
}
if (signed_response.type() == SignedMessage::SERVICE_CERTIFICATE) {
CdmResponseType status;
status = service_certificate_.Init(signed_response.msg());
if (status != NO_ERROR) {
LOGE(
"CdmEngine::ParseServiceCertificateResponse: certificate handling "
"failure, status=%d", status);
return PARSE_SERVICE_CERTIFICATE_ERROR;
}
certificate->assign(signed_response.msg());
} else if (signed_response.type() == SignedMessage::ERROR_RESPONSE) {
LicenseError license_error;
if (!license_error.ParseFromString(signed_response.msg())) {
LOGE("CdmEngine::ParseServiceCertificateResponse: cannot parse "
"license error");
return PARSE_RESPONSE_ERROR_2;
}
LOGE("CdmEngine::ParseServiceCertificateResponse: server returned error:"
"error code = %d", license_error.error_code());
return PARSE_RESPONSE_ERROR_3;
} else {
LOGE(
"CdmEngine::ParseServiceCertificateResponse: response (%d) is "
"wrong type", signed_response.type());
return PARSE_RESPONSE_ERROR_4;
}
return NO_ERROR;
}
CdmResponseType CdmEngine::OpenSession(
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
const CdmSessionId& forced_session_id, WvCdmEventListener* event_listener) {
@@ -198,8 +134,8 @@ CdmResponseType CdmEngine::OpenSession(
scoped_ptr<CdmSession> new_session(new CdmSession(file_system_,
metrics_.AddSession()));
CdmResponseType sts = new_session->Init(&service_certificate_, property_set,
forced_session_id, event_listener);
CdmResponseType sts = new_session->Init(property_set, forced_session_id,
event_listener);
if (sts != NO_ERROR) {
if (sts == NEED_PROVISIONING) {
cert_provisioning_requested_security_level_ =

View File

@@ -66,11 +66,10 @@ CdmSession::~CdmSession() {
CdmResponseType CdmSession::Init(
CdmClientPropertySet* cdm_client_property_set) {
return Init(NULL, cdm_client_property_set, NULL, NULL);
return Init(cdm_client_property_set, NULL, NULL);
}
CdmResponseType CdmSession::Init(
ServiceCertificate* service_certificate,
CdmClientPropertySet* cdm_client_property_set,
const CdmSessionId* forced_session_id, WvCdmEventListener* event_listener) {
if (initialized_) {
@@ -168,9 +167,14 @@ CdmResponseType CdmSession::Init(
policy_engine_.reset(new PolicyEngine(
session_id_, event_listener, crypto_session_.get()));
std::string service_certificate;
if (!Properties::GetServiceCertificate(session_id_, &service_certificate))
service_certificate.clear();
if (!license_parser_->Init(
service_certificate, client_token, client_token_type,
serial_number, crypto_session_.get(), policy_engine_.get()))
client_token, client_token_type, serial_number,
Properties::UsePrivacyMode(session_id_), service_certificate,
crypto_session_.get(), policy_engine_.get()))
return LICENSE_PARSER_INIT_ERROR;
license_received_ = false;

View File

@@ -172,6 +172,7 @@ CdmLicense::CdmLicense(const CdmSessionId& session_id)
initialized_(false),
renew_with_client_id_(false),
is_offline_(false),
use_privacy_mode_(false),
clock_(new Clock()) {}
CdmLicense::CdmLicense(const CdmSessionId& session_id, Clock* clock)
@@ -180,16 +181,18 @@ CdmLicense::CdmLicense(const CdmSessionId& session_id, Clock* clock)
session_id_(session_id),
initialized_(false),
renew_with_client_id_(false),
is_offline_(false) {
is_offline_(false),
use_privacy_mode_(false) {
clock_.reset(clock);
}
CdmLicense::~CdmLicense() {}
bool CdmLicense::Init(
ServiceCertificate* service_certificate, const std::string& client_token,
CdmClientTokenType client_token_type, const std::string& device_id,
CryptoSession* session, PolicyEngine* policy_engine) {
const std::string& client_token, CdmClientTokenType client_token_type,
const std::string& device_id, bool use_privacy_mode,
const std::string& signed_service_certificate, CryptoSession* session,
PolicyEngine* policy_engine) {
if (clock_.get() == NULL) {
LOGE("CdmLicense::Init: clock parameter not provided");
return false;
@@ -211,12 +214,24 @@ bool CdmLicense::Init(
return false;
}
service_certificate_ = service_certificate;
if (use_privacy_mode) {
if (!signed_service_certificate.empty()) {
if (service_certificate_.Init(signed_service_certificate) != NO_ERROR)
return false;
}
if (!service_certificate_.has_certificate() &&
!Properties::allow_service_certificate_requests()) {
LOGE("CdmLicense::Init: Required service certificate not provided");
return false;
}
}
client_token_ = client_token;
client_token_type_ = client_token_type;
device_id_ = device_id;
crypto_session_ = session;
policy_engine_ = policy_engine;
use_privacy_mode_ = use_privacy_mode;
initialized_ = true;
return true;
}
@@ -229,6 +244,12 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
LOGE("CdmLicense::PrepareKeyRequest: not initialized");
return LICENSE_PARSER_NOT_INITIALIZED_4;
}
if (init_data.IsEmpty() && stored_init_data_.get()) {
InitializationData restored_init_data = *stored_init_data_;
stored_init_data_.reset();
return PrepareKeyRequest(restored_init_data, license_type, app_parameters,
signed_request, server_url);
}
if (!init_data.is_supported()) {
LOGE("CdmLicense::PrepareKeyRequest: unsupported init data type (%s)",
init_data.type().c_str());
@@ -247,12 +268,25 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
return INVALID_PARAMETERS_LIC_7;
}
// If privacy mode, must have service certificate
if (Properties::UsePrivacyMode(session_id_) &&
!service_certificate_->has_certificate()) {
LOGE("CdmLicense::PrepareKeyRequest: failure with privacy mode - "
// If privacy mode and no service certificate, depending on platform
// configuration, request service certificate or declare error
if (use_privacy_mode_ && !service_certificate_.has_certificate()) {
if (!Properties::allow_service_certificate_requests()) {
LOGE("CdmLicense::PrepareKeyRequest: failure with privacy mode - "
"no service certificate.");
return PRIVACY_MODE_ERROR_1;
return PRIVACY_MODE_ERROR_1;
}
stored_init_data_.reset(new InitializationData(init_data));
if (!ServiceCertificate::GetRequest(signed_request)) {
LOGE("CdmLicense::PrepareKeyRequest: failed to prepare a service "
"certificated request");
return LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR;
}
return KEY_MESSAGE;
}
std::string request_id;
@@ -367,8 +401,7 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
}
if (renew_with_client_id_) {
if (Properties::UsePrivacyMode(session_id_) &&
!service_certificate_->has_certificate()) {
if (use_privacy_mode_ && !service_certificate_.has_certificate()) {
LOGE("CdmLicense::PrepareKeyUpdateRequest: failure with privacy mode - "
"no service certificate.");
return PRIVACY_MODE_ERROR_2;
@@ -490,16 +523,26 @@ CdmResponseType CdmLicense::HandleKeyResponse(
return INVALID_LICENSE_RESPONSE;
}
switch (signed_response.type()) {
case SignedMessage::LICENSE:
break;
case SignedMessage::ERROR_RESPONSE:
return HandleKeyErrorResponse(signed_response);
default:
LOGE(
"CdmLicense::HandleKeyResponse: unrecognized signed message type: %d",
signed_response.type());
return INVALID_LICENSE_TYPE;
if (use_privacy_mode_ &&
Properties::allow_service_certificate_requests() &&
signed_response.type() == SignedMessage::SERVICE_CERTIFICATE) {
std::string signed_certificate;
CdmResponseType status =
ServiceCertificate::ParseResponse(license_response,
&signed_certificate);
if (status != NO_ERROR) return status;
status = service_certificate_.Init(signed_certificate);
return (status == NO_ERROR) ? NEED_KEY : status;
}
if (signed_response.type() == SignedMessage::ERROR_RESPONSE)
return HandleKeyErrorResponse(signed_response);
if (signed_response.type() != SignedMessage::LICENSE) {
LOGE("CdmLicense::HandleKeyResponse: unrecognized signed message type: %d",
signed_response.type());
return INVALID_LICENSE_TYPE;
}
if (!signed_response.has_signature()) {
@@ -1108,15 +1151,15 @@ CdmResponseType CdmLicense::PrepareClientId(
client_capabilities->set_srm_version(srm_version);
if (Properties::UsePrivacyMode(session_id_)) {
if (service_certificate_->certificate().empty()) {
if (!service_certificate_.has_certificate()) {
LOGE("CdmLicense::PrepareClientId: Service Certificate not staged");
return PRIVACY_MODE_ERROR_3;
}
EncryptedClientIdentification* encrypted_client_id =
license_request->mutable_encrypted_client_id();
CdmResponseType status;
status = service_certificate_->EncryptClientId(crypto_session_, client_id,
encrypted_client_id);
status = service_certificate_.EncryptClientId(crypto_session_, client_id,
encrypted_client_id);
if (NO_ERROR == status) {
license_request->clear_client_id();
} else {

View File

@@ -108,7 +108,7 @@ typedef OEMCryptoResult (*L1_DecryptCTR_V10_t)(
typedef OEMCryptoResult (*L1_DecryptCENC_t)(
OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length,
bool is_encrypted, const uint8_t* iv, size_t offset,
const OEMCrypto_DestBufferDesc* out_buffer,
OEMCrypto_DestBufferDesc* out_buffer,
const OEMCrypto_CENCEncryptPatternDesc* pattern, uint8_t subsample_flags);
typedef OEMCryptoResult (*L1_CopyBuffer_t)(const uint8_t* data_addr,
size_t data_length,
@@ -322,61 +322,6 @@ struct FunctionPointers {
L1_DeactivateUsageEntry_V12_t DeactivateUsageEntry_V12;
};
// The Cache Flush function is very processor dependent, but is needed by the
// haystack code. The haystack code is delivered as a static prebuilt library.
// For that reason, we pass a function pointer for cache_flush into the
// haystack. The function is compiled outside of the haystack and may use
// target (processor) specific compiler flags.
void clear_cache_function(void *page, size_t len) {
// Note on cross platform support. If __has_builtin is not defined as a
// preprocessor function, we cannot use
// "#if defined(__has_builtin) && __has_builtin(..)".
// So, instead, we will define USED_BUILTIN_CLEAR_CACHE if both conditions
// are true, and use "#ifndef USED_BUILTIN_CLEAR_CACHE" instead of #else.
#ifdef __has_builtin
#if __has_builtin(__builtin___clear_cache)
#pragma message "(info): clear_cache_function is using __builtin___clear_cache."
#define USED_BUILTIN_CLEAR_CACHE
char *begin = static_cast<char *>(page);
char *end = begin + len;
__builtin___clear_cache(begin, end);
#endif
#endif
#ifndef USED_BUILTIN_CLEAR_CACHE
#if __arm__
#pragma message "(info): clear_cache_function is using arm asm."
// ARM Cache Flush System Call:
char *begin = static_cast<char *>(page);
char *end = begin + len;
const int syscall = 0xf0002;
__asm __volatile (
"push {r0, r1, r2, r7}\n"
"mov r0, %0\n"
"mov r1, %1\n"
"mov r7, %2\n"
"mov r2, #0x0\n"
"svc 0x00000000\n"
"pop {r0, r1, r2, r7}\n"
:
: "r" (begin), "r" (end), "r" (syscall)
: "r0", "r1", "r7"
);
#elif __mips__
#pragma message "(info): clear_cache_function is using mips asm."
int result = syscall(__NR_cacheflush, page, len, ICACHE);
if (result) {
fprintf(stderr, "cacheflush failed!: errno=%d %s\n", errno,
strerror(errno));
exit(-1); // TODO(fredgc): figure out more graceful error handling.
}
#else
#pragma message "(info): clear_cache_function is not doing anything."
// TODO(fredgc): silence warning about unused variables.
#endif
#endif
}
// The WatchDog looks after a worker thread that is trying to initialize L3.
// Once in a rare while, the L3 init does not finish and eats up CPU cycles.
// If that happens, the watchdog thread will give up and return an error.
@@ -416,11 +361,7 @@ class WatchDog {
// Called by worker thread.
void DoInit() {
std::string base_path;
wvcdm::Properties::GetDeviceFilesBasePath(wvcdm::kSecurityLevelL3,
&base_path);
status_ = Level3_Initialize(clear_cache_function,
base_path.c_str());
status_ = Level3_Initialize();
}
std::string FailureFilename() {

View File

@@ -4,6 +4,7 @@
#include "crypto_key.h"
#include "crypto_session.h"
#include "license_protocol.pb.h"
#include "log.h"
#include "privacy_crypto.h"
#include "properties.h"
@@ -123,6 +124,7 @@ namespace wvcdm {
using video_widevine::ClientIdentification;
using video_widevine::DrmDeviceCertificate;
using video_widevine::EncryptedClientIdentification;
using video_widevine::LicenseError;
using video_widevine::SignedDrmDeviceCertificate;
using video_widevine::SignedMessage;
@@ -245,4 +247,55 @@ CdmResponseType ServiceCertificate::EncryptClientId(
return NO_ERROR;
}
bool ServiceCertificate::GetRequest(CdmKeyMessage* request) {
if (!request) {
LOGE("ServiceCertificate::PrepareRequest: no request parameter provided");
return false;
}
SignedMessage message;
message.set_type(SignedMessage::SERVICE_CERTIFICATE_REQUEST);
message.SerializeToString(request);
return true;
}
CdmResponseType ServiceCertificate::ParseResponse(
const std::string& response, std::string* certificate) {
if (response.empty()) {
LOGE("ServiceCertificate::ParseResponse: empty response");
return EMPTY_RESPONSE_ERROR_1;
}
if (!certificate) {
LOGE("ServiceCertificate::ParseResponse: null return parameter");
return INVALID_PARAMETERS_ENG_24;
}
SignedMessage signed_response;
if (!signed_response.ParseFromString(response)) {
LOGE("ServiceCertificate::ParseResponse: cannot parse response");
return PARSE_RESPONSE_ERROR_1;
}
if (signed_response.type() == SignedMessage::ERROR_RESPONSE) {
LicenseError license_error;
if (!license_error.ParseFromString(signed_response.msg())) {
LOGE("ServiceCertificate::ParseResponse: cannot parse license error");
return PARSE_RESPONSE_ERROR_2;
}
LOGE("ServiceCertificate::ParseResponse: server returned error = %d",
license_error.error_code());
return PARSE_RESPONSE_ERROR_3;
}
if (signed_response.type() != SignedMessage::SERVICE_CERTIFICATE) {
LOGE("ServiceCertificate::ParseResponse: response (%d) is wrong type",
signed_response.type());
return PARSE_RESPONSE_ERROR_4;
}
certificate->assign(signed_response.msg());
return NO_ERROR;
}
} // namespace wvcdm

View File

@@ -130,6 +130,8 @@ class WvCdmEnginePreProvTest : public testing::Test {
status = cdm_engine_.OpenSession(g_key_system, NULL, NULL, &session_id_);
}
ASSERT_EQ(status, NO_ERROR);
ASSERT_NE("", session_id_) << "Could not open CDM session.";
ASSERT_TRUE(cdm_engine_.IsOpenSession(session_id_));
session_opened_ = true;
}
@@ -183,9 +185,19 @@ class WvCdmEnginePreProvTest : public testing::Test {
std::string cert, wrapped_key;
ASSERT_EQ(NO_ERROR, cdm_engine_.SetServiceCertificate(
g_provisioning_service_certificate));
ASSERT_EQ(NO_ERROR, cdm_engine_.GetProvisioningRequest(
cert_type, cert_authority, &prov_request,
&provisioning_server_url));
CdmResponseType result = NO_ERROR;
for(int i = 0; i < 2; ++i) { // Retry once if there is a nonce problem.
result = cdm_engine_.GetProvisioningRequest(
cert_type, cert_authority, &prov_request,
&provisioning_server_url);
if (result == CERT_PROVISIONING_NONCE_GENERATION_ERROR) {
LOGW("Woops. Nonce problem. Try again?");
sleep(1);
} else {
break;
}
}
ASSERT_EQ(NO_ERROR, result);
LOGV("WvCdmEnginePreProvTest::Provision: req=%s", prov_request.c_str());
@@ -472,83 +484,6 @@ TEST_F(WvCdmEnginePreProvTestStaging, ServiceCertificateGoodTest) {
ASSERT_TRUE(cdm_engine_.HasServiceCertificate());
};
// Test that service certificate can be retrieved from the license server.
TEST_F(WvCdmEnginePreProvTestStaging, ServiceCertificateRequestResponse) {
CdmKeyMessage request;
std::string certificate;
// Initial condition - no service certificate.
ASSERT_FALSE(cdm_engine_.HasServiceCertificate());
// Generate request.
// The request will be a serialized protobuf message.
ASSERT_TRUE(cdm_engine_.GetServiceCertificateRequest(&request));
std::string response;
ASSERT_TRUE(LicenseServerRequestResponse(request, &response));
// Extract the service certificate
ASSERT_EQ(cdm_engine_.ParseServiceCertificateResponse(response, &certificate),
NO_ERROR);
ASSERT_TRUE(cdm_engine_.HasServiceCertificate());
LOGV("ret'd service certificate:\n%s\n", b2a_hex(certificate).c_str());
};
// Test that service certificate can be retrieved from the license server.
TEST_F(WvCdmEnginePreProvTestUat, ServiceCertificateRequestResponse) {
CdmKeyMessage request;
std::string certificate;
// Initial condition - no service certificate.
ASSERT_FALSE(cdm_engine_.HasServiceCertificate());
// Generate request.
// The request will be a serialized protobuf message.
ASSERT_TRUE(cdm_engine_.GetServiceCertificateRequest(&request));
std::string response;
ASSERT_TRUE(LicenseServerRequestResponse(request, &response));
// Extract the service certificate
ASSERT_EQ(cdm_engine_.ParseServiceCertificateResponse(response, &certificate),
NO_ERROR);
ASSERT_TRUE(cdm_engine_.HasServiceCertificate());
LOGV("ret'd service certificate:\n%s\n", b2a_hex(certificate).c_str());
};
// Test that service certificate can be retrieved from the license server.
TEST_F(WvCdmEnginePreProvTestProd, ServiceCertificateRequestResponse) {
CdmKeyMessage request;
std::string certificate;
// Initial condition - no service certificate.
ASSERT_FALSE(cdm_engine_.HasServiceCertificate());
// Generate request.
// The request will be a serialized protobuf message.
ASSERT_TRUE(cdm_engine_.GetServiceCertificateRequest(&request));
std::string response;
ASSERT_TRUE(LicenseServerRequestResponse(request, &response));
// Extract the service certificate
ASSERT_EQ(cdm_engine_.ParseServiceCertificateResponse(response, &certificate),
NO_ERROR);
ASSERT_TRUE(cdm_engine_.HasServiceCertificate());
LOGV("ret'd service certificate:\n%s\n", b2a_hex(certificate).c_str());
};
// Test that empty service certificate fails.
TEST_F(WvCdmEnginePreProvTestStaging, ServiceCertificateEmptyFailTest) {
std::string empty_cert;
ASSERT_EQ(cdm_engine_.SetServiceCertificate(g_license_service_certificate),
NO_ERROR);
ASSERT_TRUE(cdm_engine_.HasServiceCertificate());
};
// Test that provisioning works, even if device is already provisioned.
TEST_F(WvCdmEnginePreProvTestStaging, DISABLED_ProvisioningTest) {
uint32_t nonce = 0;

View File

@@ -126,8 +126,8 @@ class MockCdmLicense : public CdmLicense {
MockCdmLicense(const CdmSessionId& session_id)
: CdmLicense(session_id) {}
MOCK_METHOD6(Init, bool(ServiceCertificate*, const std::string&,
CdmClientTokenType, const std::string&,
MOCK_METHOD7(Init, bool(const std::string&, CdmClientTokenType,
const std::string&, bool, const std::string&,
CryptoSession*, PolicyEngine*));
};
@@ -192,8 +192,9 @@ TEST_F(CdmSessionTest, InitWithBuiltInCertificate) {
.WillOnce(Return(true));
EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true));
EXPECT_CALL(*license_parser_,
Init(NULL, Eq(kToken), Eq(kClientTokenDrmCert),
Eq(kEmptyString), Eq(crypto_session_), Eq(policy_engine_)))
Init(Eq(kToken), Eq(kClientTokenDrmCert), Eq(kEmptyString),
false, Eq(kEmptyString), Eq(crypto_session_),
Eq(policy_engine_)))
.WillOnce(Return(true));
ASSERT_EQ(NO_ERROR, cdm_session_->Init(NULL));
@@ -219,8 +220,9 @@ TEST_F(CdmSessionTest, InitWithCertificate) {
.InSequence(crypto_session_seq)
.WillOnce(Return(true));
EXPECT_CALL(*license_parser_,
Init(NULL, Eq(kToken), Eq(kClientTokenDrmCert),
Eq(kEmptyString), Eq(crypto_session_), Eq(policy_engine_)))
Init(Eq(kToken), Eq(kClientTokenDrmCert), Eq(kEmptyString),
false, Eq(kEmptyString), Eq(crypto_session_),
Eq(policy_engine_)))
.WillOnce(Return(true));
ASSERT_EQ(NO_ERROR, cdm_session_->Init(NULL));
@@ -246,7 +248,7 @@ TEST_F(CdmSessionTest, ReInitFail) {
.InSequence(crypto_session_seq)
.WillOnce(Return(true));
EXPECT_CALL(*license_parser_,
Init(NULL, Eq(kToken), Eq(kClientTokenDrmCert),
Init(Eq(kToken), Eq(kClientTokenDrmCert), Eq(kEmptyString), false,
Eq(kEmptyString), Eq(crypto_session_), Eq(policy_engine_)))
.WillOnce(Return(true));

View File

@@ -36,6 +36,33 @@ const std::string kCryptoRequestId = a2bs_hex(
"4341444542353737444337393044394330313030303030303030303030303030");
const uint32_t kNonce = 0x49e81305;
const int64_t kLicenseStartTime = 1413517500; // ~ 01/01/2013
const std::string kEmptyServiceCertificate;
const std::string kInvalidServiceCertificate = "0b";
const std::string kDefaultServiceCertificate = a2bs_hex(
"0ABF020803121028703454C008F63618ADE7443DB6C4C8188BE7F9900522"
"8E023082010A0282010100B52112B8D05D023FCC5D95E2C251C1C649B417"
"7CD8D2BEEF355BB06743DE661E3D2ABC3182B79946D55FDC08DFE9540781"
"5E9A6274B322A2C7F5E067BB5F0AC07A89D45AEA94B2516F075B66EF811D"
"0D26E1B9A6B894F2B9857962AA171C4F66630D3E4C602718897F5E1EF9B6"
"AAF5AD4DBA2A7E14176DF134A1D3185B5A218AC05A4C41F081EFFF80A3A0"
"40C50B09BBC740EEDCD8F14D675A91980F92CA7DDC646A06ADAD5101F74A"
"0E498CC01F00532BAC217850BD905E90923656B7DFEFEF42486767F33EF6"
"283D4F4254AB72589390BEE55808F1D668080D45D893C2BCA2F74D60A0C0"
"D0A0993CEF01604703334C3638139486BC9DAF24FD67A07F9AD943020301"
"00013A1273746167696E672E676F6F676C652E636F6D128003983E303526"
"75F40BA715FC249BDAE5D4AC7249A2666521E43655739529721FF880E0AA"
"EFC5E27BC980DAEADABF3FC386D084A02C82537848CC753FF497B011A7DA"
"97788A00E2AA6B84CD7D71C07A48EBF61602CCA5A3F32030A7295C30DA91"
"5B91DC18B9BC9593B8DE8BB50F0DEDC12938B8E9E039CDDE18FA82E81BB0"
"32630FE955D85A566CE154300BF6D4C1BD126966356B287D657B18CE63D0"
"EFD45FC5269E97EAB11CB563E55643B26FF49F109C2101AFCAF35B832F28"
"8F0D9D45960E259E85FB5D24DBD2CF82764C5DD9BF727EFBE9C861F86932"
"1F6ADE18905F4D92F9A6DA6536DB8475871D168E870BB2303CF70C6E9784"
"C93D2DE845AD8262BE7E0D4E2E4A0759CEF82D109D2592C72429F8C01742"
"BAE2B3DECADBC33C3E5F4BAF5E16ECB74EADBAFCB7C6705F7A9E3B6F3940"
"383F9C5116D202A20C9229EE969C2519718303B50D0130C3352E06B014D8"
"38540F8A0C227C0011E0F5B38E4E298ED2CB301EB4564965F55C5D79757A"
"250A4EB9C84AB3E6539F6B6FDF56899EA29914");
const std::string kToken = a2bs_hex(
"0AAE02080212107E0A892DEEB021E7AF696B938BB1D5B1188B85AD9D05228E023082010A02"
"82010100DBEDF2BFB0EC98213766E65049B9AB176FA4B1FBFBB2A0C96C87D9F2B895E0ED77"
@@ -199,7 +226,6 @@ class CdmLicenseTest : public ::testing::Test {
MockCryptoSession* crypto_session_;
MockInitializationData* init_data_;
MockPolicyEngine* policy_engine_;
ServiceCertificate service_cert_;
std::string pssh_;
};
@@ -212,37 +238,60 @@ TEST_F(CdmLicenseTest, InitSuccess) {
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
CreateCdmLicense();
EXPECT_TRUE(cdm_license_->Init(
&service_cert_, kToken, kClientTokenDrmCert, kEmptyString,
crypto_session_, policy_engine_));
EXPECT_TRUE(cdm_license_->Init(kToken, kClientTokenDrmCert, kEmptyString,
false, kEmptyServiceCertificate,
crypto_session_, policy_engine_));
}
TEST_F(CdmLicenseTest, InitFail_EmptyToken) {
CreateCdmLicense();
EXPECT_FALSE(cdm_license_->Init(&service_cert_, "", kClientTokenDrmCert, "",
crypto_session_, policy_engine_));
EXPECT_FALSE(cdm_license_->Init("", kClientTokenDrmCert, "", false,
kEmptyServiceCertificate, crypto_session_,
policy_engine_));
}
TEST_F(CdmLicenseTest, InitFail_CryptoSessionNull) {
CreateCdmLicense();
EXPECT_FALSE(cdm_license_->Init(&service_cert_, kToken, kClientTokenDrmCert,
"", NULL, policy_engine_));
EXPECT_FALSE(cdm_license_->Init(kToken, kClientTokenDrmCert, "", false,
kEmptyServiceCertificate, NULL,
policy_engine_));
}
TEST_F(CdmLicenseTest, InitFail_PolicyEngineNull) {
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
CreateCdmLicense();
EXPECT_FALSE(cdm_license_->Init(&service_cert_, kToken, kClientTokenDrmCert,
"", crypto_session_, NULL));
EXPECT_FALSE(cdm_license_->Init(kToken, kClientTokenDrmCert, "", false,
kEmptyServiceCertificate, crypto_session_,
NULL));
}
TEST_F(CdmLicenseTest, InitWithNullServiceCert) {
TEST_F(CdmLicenseTest, InitWithEmptyServiceCert) {
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
CreateCdmLicense();
EXPECT_TRUE(cdm_license_->Init(NULL, kToken, kClientTokenDrmCert, "",
crypto_session_, policy_engine_));
EXPECT_EQ(cdm_license_->Init(kToken, kClientTokenDrmCert, "", true,
kEmptyServiceCertificate, crypto_session_,
policy_engine_),
Properties::allow_service_certificate_requests());
}
TEST_F(CdmLicenseTest, InitWithInvalidServiceCert) {
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
CreateCdmLicense();
EXPECT_FALSE(cdm_license_->Init(kToken, kClientTokenDrmCert, "", true,
kInvalidServiceCertificate, crypto_session_,
policy_engine_));
}
TEST_F(CdmLicenseTest, InitWithServiceCert) {
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
CreateCdmLicense();
EXPECT_TRUE(cdm_license_->Init(kToken, kClientTokenDrmCert, "", true,
kDefaultServiceCertificate, crypto_session_,
policy_engine_));
}
TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) {
@@ -274,8 +323,8 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) {
CreateCdmLicense();
EXPECT_TRUE(cdm_license_->Init(
&service_cert_, kToken, kClientTokenDrmCert, kEmptyString,
crypto_session_, policy_engine_));
kToken, kClientTokenDrmCert, kEmptyString, true,
kDefaultServiceCertificate, crypto_session_, policy_engine_));
CdmAppParameterMap app_parameters;
CdmKeyMessage signed_request;
@@ -405,11 +454,9 @@ TEST_F(SubLicenseTest, VerifySubSessionData) {
DoAll(SetArgPointee<1>(true), SetArgPointee<2>(2), Return(true)));
CreateCdmLicense();
// TODO(gmorgan) fix below - no default service certificate
//service_cert_.Init(kDefaultServiceCertificate);
EXPECT_TRUE(cdm_license_->Init(
&service_cert_, kToken, kClientTokenDrmCert, kEmptyString,
crypto_session_, policy_engine_));
kToken, kClientTokenDrmCert, kEmptyString, true,
kDefaultServiceCertificate, crypto_session_, policy_engine_));
CdmAppParameterMap app_parameters;
CdmKeyMessage signed_request;
std::string server_url;

View File

@@ -1648,7 +1648,7 @@ TEST_F(WvCdmRequestLicenseTest, PrivacyModeWithServiceCertificateTest) {
TestWvCdmClientPropertySet property_set;
property_set.set_use_privacy_mode(true);
property_set.set_service_certificate(a2bs_hex(g_service_certificate));
property_set.set_service_certificate(g_service_certificate);
// TODO: pass g_service_certificate into CdmEngine::SetServiceCertificate()
decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier,
NULL, &session_id_);
@@ -2177,7 +2177,7 @@ TEST_P(WvCdmStreamingLicenseRenewalTest, WithClientId) {
if (config->enable_privacy_mode) {
property_set.set_use_privacy_mode(true);
if (config->specify_service_certificate)
property_set.set_service_certificate(a2bs_hex(g_service_certificate));
property_set.set_service_certificate(g_service_certificate);
}
// TODO: pass g_service_certificate into CdmEngine::SetServiceCertificate()
decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier,
@@ -2308,7 +2308,7 @@ TEST_P(WvCdmOfflineLicenseReleaseTest, WithClientId) {
if (config->enable_privacy_mode) {
property_set.set_use_privacy_mode(true);
if (config->specify_service_certificate)
property_set.set_service_certificate(a2bs_hex(g_service_certificate));
property_set.set_service_certificate(g_service_certificate);
}
// TODO: pass g_service_certificate into CdmEngine::SetServiceCertificate()
decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier,
@@ -3922,7 +3922,7 @@ int main(int argc, char** argv) {
}
case 's': {
g_service_certificate.clear();
g_service_certificate.assign(optarg);
g_service_certificate.assign(wvcdm::a2bs_hex(optarg));
break;
}
case 'u': {

View File

@@ -318,6 +318,8 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) {
return kInvalidParametersLic6;
case wvcdm::INVALID_PARAMETERS_LIC_7:
return kInvalidParametersLic7;
case wvcdm::LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR:
return kLicenseRequestServiceCertificateGenerationError;
case wvcdm::CENC_INIT_DATA_UNAVAILABLE:
return kCencInitDataUnavailable;
case wvcdm::PREPARE_CENC_CONTENT_ID_FAILED:
@@ -546,7 +548,6 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) {
case wvcdm::UNUSED_6:
case wvcdm::UNUSED_7:
case wvcdm::UNUSED_8:
case wvcdm::UNUSED_9:
case wvcdm::UNUSED_10:
return android::UNKNOWN_ERROR;
}

View File

@@ -199,6 +199,7 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) {
case wvcdm::UNSUPPORTED_INIT_DATA_FORMAT:
case wvcdm::LICENSE_REQUEST_INVALID_SUBLICENSE:
case wvcdm::LICENSE_REQUEST_NONCE_GENERATION_ERROR:
case wvcdm::LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR:
case wvcdm::LICENSE_REQUEST_SIGNING_ERROR:
case wvcdm::EMPTY_LICENSE_REQUEST:
case wvcdm::DUPLICATE_SESSION_ID_SPECIFIED:
@@ -317,7 +318,6 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) {
case wvcdm::UNUSED_6:
case wvcdm::UNUSED_7:
case wvcdm::UNUSED_8:
case wvcdm::UNUSED_9:
case wvcdm::UNUSED_10:
return Status::ERROR_DRM_UNKNOWN;
}

View File

@@ -16,6 +16,7 @@
namespace wvoec3 {
#ifdef DYNAMIC_ADAPTER
#define Level3_IsInApp _lcc00
#define Level3_Initialize _lcc01
#define Level3_Terminate _lcc02
@@ -77,11 +78,73 @@ namespace wvoec3 {
#define Level3_MoveEntry _lcc68
#define Level3_CopyOldUsageEntry _lcc69
#define Level3_CreateOldUsageEntry _lcc70
#else
#define Level3_Initialize _oecc01
#define Level3_Terminate _oecc02
#define Level3_InstallKeybox _oecc03
#define Level3_GetKeyData _oecc04
#define Level3_IsKeyboxValid _oecc05
#define Level3_GetRandom _oecc06
#define Level3_GetDeviceID _oecc07
#define Level3_WrapKeybox _oecc08
#define Level3_OpenSession _oecc09
#define Level3_CloseSession _oecc10
#define Level3_GenerateDerivedKeys _oecc12
#define Level3_GenerateSignature _oecc13
#define Level3_GenerateNonce _oecc14
#define Level3_RefreshKeys _oecc16
#define Level3_SelectKey _oecc17
#define Level3_RewrapDeviceRSAKey _oecc18
#define Level3_LoadDeviceRSAKey _oecc19
#define Level3_DeriveKeysFromSessionKey _oecc21
#define Level3_APIVersion _oecc22
#define Level3_SecurityLevel _oecc23
#define Level3_Generic_Encrypt _oecc24
#define Level3_Generic_Decrypt _oecc25
#define Level3_Generic_Sign _oecc26
#define Level3_Generic_Verify _oecc27
#define Level3_SupportsUsageTable _oecc29
#define Level3_UpdateUsageTable _oecc30
#define Level3_ReportUsage _oecc32
#define Level3_DeleteUsageEntry _oecc33
#define Level3_DeleteOldUsageTable _oecc34
#define Level3_GenerateRSASignature _oecc36
#define Level3_GetMaxNumberOfSessions _oecc37
#define Level3_GetNumberOfOpenSessions _oecc38
#define Level3_IsAntiRollbackHwPresent _oecc39
#define Level3_CopyBuffer _oecc40
#define Level3_QueryKeyControl _oecc41
#define Level3_LoadTestKeybox _oecc42
#define Level3_ForceDeleteUsageEntry _oecc43
#define Level3_GetHDCPCapability _oecc44
#define Level3_LoadTestRSAKey _oecc45
#define Level3_SecurityPatchLevel _oecc46
#define Level3_DecryptCENC _oecc48
#define Level3_GetProvisioningMethod _oecc49
#define Level3_GetOEMPublicCertificate _oecc50
#define Level3_RewrapDeviceRSAKey30 _oecc51
#define Level3_SupportedCertificates _oecc52
#define Level3_IsSRMUpdateSupported _oecc53
#define Level3_GetCurrentSRMVersion _oecc54
#define Level3_LoadSRM _oecc55
#define Level3_LoadKeys _oecc56
#define Level3_RemoveSRM _oecc57
#define Level3_CreateUsageTableHeader _oecc61
#define Level3_LoadUsageTableHeader _oecc62
#define Level3_CreateNewUsageEntry _oecc63
#define Level3_LoadUsageEntry _oecc64
#define Level3_UpdateUsageEntry _oecc65
#define Level3_DeactivateUsageEntry _oecc66
#define Level3_ShrinkUsageTableHeader _oecc67
#define Level3_MoveEntry _oecc68
#define Level3_CopyOldUsageEntry _oecc69
#define Level3_CreateOldUsageEntry _oecc70
#endif
extern "C" {
bool Level3_IsInApp();
OEMCryptoResult Level3_Initialize(void (*ClearCache)(void *, size_t),
const char* base_path);
OEMCryptoResult Level3_Initialize(void);
OEMCryptoResult Level3_Terminate(void);
OEMCryptoResult Level3_OpenSession(OEMCrypto_SESSION *session);
OEMCryptoResult Level3_CloseSession(OEMCrypto_SESSION session);
@@ -124,7 +187,7 @@ OEMCryptoResult Level3_DecryptCENC(OEMCrypto_SESSION session,
bool is_encrypted,
const uint8_t *iv,
size_t block_offset,
const OEMCrypto_DestBufferDesc* out_buffer,
OEMCrypto_DestBufferDesc* out_buffer,
const OEMCrypto_CENCEncryptPatternDesc* pattern,
uint8_t subsample_flags);
OEMCryptoResult Level3_CopyBuffer(const uint8_t *data_addr,

View File

@@ -8,6 +8,7 @@ endif
LOCAL_SRC_FILES:= \
oec_device_features.cpp \
oec_session_util.cpp \
oemcrypto_session_tests_helper.cpp \
oemcrypto_test.cpp \
oemcrypto_test_android.cpp \
oemcrypto_test_main.cpp \