Snap for 7168754 from 1ffc6ab16a to sc-release

Change-Id: I543b3fea681142d825c4ef6d8fc1e5538ad39aaf
This commit is contained in:
android-build-team Robot
2021-02-25 02:18:01 +00:00
12 changed files with 325 additions and 125 deletions

View File

@@ -0,0 +1,112 @@
#!/bin/sh
set -e
if [ -z "$ANDROID_BUILD_TOP" ]; then
echo "Android build environment not set"
exit -1
fi
# Read arguments in case the user wants to do a multicore build or
# copy files to a specific android device by providing a serial number
NUM_CORES=1
SERIAL_NUM=""
while getopts "j:s:" opt; do
case $opt in
j)
NUM_CORES=$OPTARG
;;
s)
SERIAL_NUM="-s $OPTARG"
;;
esac
done
# Define the relevant aliases
. $ANDROID_BUILD_TOP/build/envsetup.sh
# Build all the targets
# This list is slightly longer than the one in run_all_unit_tests.sh because
# it does not run very long tests or tests needing special setup.
WV_TEST_TARGETS="base64_test \
buffer_reader_test \
cdm_engine_test \
cdm_engine_metrics_decorator_unittest \
cdm_feature_test \
cdm_extended_duration_test \
cdm_session_unittest \
certificate_provisioning_unittest \
counter_metric_unittest \
crypto_session_unittest \
device_files_unittest \
distribution_unittest \
duration_use_case_test \
event_metric_unittest \
file_store_unittest \
file_utils_unittest \
generic_crypto_unittest \
hidl_metrics_adapter_unittest \
http_socket_test \
initialization_data_unittest \
libwvdrmdrmplugin_hidl_test \
libwvdrmdrmplugin_test \
libwvdrmengine_hidl_test \
libwvdrmengine_test \
libwvdrmmediacrypto_hidl_test \
libwvdrmmediacrypto_test \
license_keys_unittest \
license_unittest \
metrics_collections_unittest \
oemcrypto_test \
odk_test \
policy_engine_constraints_unittest \
policy_engine_unittest \
policy_integration_test \
request_license_test \
rw_lock_test \
service_certificate_unittest \
timer_unittest \
usage_table_header_unittest \
value_metric_unittest \
wv_cdm_metrics_test"
cd $ANDROID_BUILD_TOP
pwd
m -j $NUM_CORES $WV_TEST_TARGETS
# Detect the device and check if Verity is going to stop the script from working
echo "waiting for device"
ADB_OUTPUT=`adb $SERIAL_NUM root && echo ". " && adb $SERIAL_NUM wait-for-device remount`
echo $ADB_OUTPUT
if echo $ADB_OUTPUT | grep -qi "verity"; then
echo
echo "ERROR: This device has Verity enabled. build_and_run_all_unit_tests.sh "
echo "does not work if Verity is enabled. Please disable Verity with"
echo "\"adb $SERIAL_NUM disable-verity\" and try again."
exit -1
fi
# Push the files to the device
# Given a local path to a file, this will try to push it to /data/nativetest.
# If that fails, an error message will be printed.
try_adb_push() {
# android-tests.zip requires /data/nativetest, we should use the same
if [ -f $OUT/data/nativetest/$1 ]; then
test_file=$OUT/data/nativetest/$1
elif [ -f $OUT/data/nativetest/vendor/$1/$1 ]; then
test_file=$OUT/data/nativetest/vendor/$1/$1
else
echo "I cannot find $1"
echo "I think it should be in $OUT/data/nativetest"
exit 1
fi
adb $SERIAL_NUM shell mkdir -p /data/nativetest
adb $SERIAL_NUM push $test_file /data/nativetest/$1
}
# Push the tests to the device
for f in $WV_TEST_TARGETS; do
try_adb_push $f
done

View File

@@ -1,116 +1,9 @@
#!/bin/sh
set -e
if [ -z "$ANDROID_BUILD_TOP" ]; then
echo "Android build environment not set"
exit -1
fi
# Read arguments in case the user wants to do a multicore build or
# copy files to a specific android device by providing a serial number
NUM_CORES=1
SERIAL_NUM=""
while getopts "j:s:" opt; do
case $opt in
j)
NUM_CORES=$OPTARG
;;
s)
SERIAL_NUM="-s $OPTARG"
;;
esac
done
# Define the relevant aliases
. $ANDROID_BUILD_TOP/build/envsetup.sh
# Build all the targets
# This list is slightly longer than the one in run_all_unit_tests.sh because
# it does not run very long tests or tests needing special setup.
WV_TEST_TARGETS="base64_test \
buffer_reader_test \
cdm_engine_test \
cdm_engine_metrics_decorator_unittest \
cdm_feature_test \
cdm_extended_duration_test \
cdm_session_unittest \
certificate_provisioning_unittest \
counter_metric_unittest \
crypto_session_unittest \
device_files_unittest \
distribution_unittest \
duration_use_case_test \
event_metric_unittest \
file_store_unittest \
file_utils_unittest \
generic_crypto_unittest \
hidl_metrics_adapter_unittest \
http_socket_test \
initialization_data_unittest \
libwvdrmdrmplugin_hidl_test \
libwvdrmdrmplugin_test \
libwvdrmengine_hidl_test \
libwvdrmengine_test \
libwvdrmmediacrypto_hidl_test \
libwvdrmmediacrypto_test \
license_keys_unittest \
license_unittest \
metrics_collections_unittest \
oemcrypto_test \
odk_test \
policy_engine_constraints_unittest \
policy_engine_unittest \
policy_integration_test \
request_license_test \
rw_lock_test \
service_certificate_unittest \
timer_unittest \
usage_table_header_unittest \
value_metric_unittest \
wv_cdm_metrics_test"
cd $ANDROID_BUILD_TOP
pwd
m -j $NUM_CORES $WV_TEST_TARGETS
# Detect the device and check if Verity is going to stop the script from working
echo "waiting for device"
ADB_OUTPUT=`adb $SERIAL_NUM root && echo ". " && adb $SERIAL_NUM wait-for-device remount`
echo $ADB_OUTPUT
if echo $ADB_OUTPUT | grep -qi "verity"; then
echo
echo "ERROR: This device has Verity enabled. build_and_run_all_unit_tests.sh "
echo "does not work if Verity is enabled. Please disable Verity with"
echo "\"adb $SERIAL_NUM disable-verity\" and try again."
exit -1
fi
# Push the files to the device
# Given a local path to a file, this will try to push it to /data/nativetest.
# If that fails, an error message will be printed.
try_adb_push() {
# android-tests.zip requires /data/nativetest, we should use the same
if [ -f $OUT/data/nativetest/$1 ]; then
test_file=$OUT/data/nativetest/$1
elif [ -f $OUT/data/nativetest/vendor/$1/$1 ]; then
test_file=$OUT/data/nativetest/vendor/$1/$1
else
echo "I cannot find $1"
echo "I think it should be in $OUT/data/nativetest"
exit 1
fi
adb $SERIAL_NUM shell mkdir -p /data/nativetest
adb $SERIAL_NUM push $test_file /data/nativetest/$1
}
# Push the tests to the device
for f in $WV_TEST_TARGETS; do
try_adb_push $f
done
# Build the tests using build_all_unit_tests.sh
cd $ANDROID_BUILD_TOP/vendor/widevine/libwvdrmengine
./build_all_unit_tests.sh "$@"
# Run the tests using run_all_unit_tests.sh
cd $ANDROID_BUILD_TOP/vendor/widevine/libwvdrmengine
./run_all_unit_tests.sh $SERIAL_NUM
./run_all_unit_tests.sh "$@"

View File

@@ -68,8 +68,8 @@ class CertificateProvisioning {
const std::string& origin, const std::string& spoid,
video_widevine::ProvisioningRequest* request);
video_widevine::SignedProvisioningMessage::ProtocolVersion
GetProtocolVersion();
video_widevine::SignedProvisioningMessage::ProvisioningType
GetProvisioningType();
std::unique_ptr<CryptoSession> crypto_session_;
CdmCertificateType cert_type_;

View File

@@ -418,6 +418,7 @@ enum CdmResponseType : int32_t {
NO_SRM_VERSION = 363,
SESSION_NOT_FOUND_23 = 364,
CERT_PROVISIONING_RESPONSE_ERROR_9 = 365,
CERT_PROVISIONING_RESPONSE_ERROR_10 = 366,
// Don't forget to add new values to
// * core/test/test_printers.cpp.
// * android/include/mapErrors-inl.h

View File

@@ -118,6 +118,7 @@ using video_widevine::ProvisioningRequest;
using video_widevine::ProvisioningResponse;
using video_widevine::SignedDrmDeviceCertificate;
using video_widevine::SignedProvisioningMessage;
using video_widevine::SignedProvisioningMessage_ProvisioningProtocolVersion_VERSION_1_1;
CdmResponseType CertificateProvisioning::Init(
const std::string& service_certificate) {
@@ -172,8 +173,8 @@ CdmResponseType CertificateProvisioning::SetSpoidParameter(
* Return the provisioning protocol version - dictated by OEMCrypto
* support for OEM certificates.
*/
SignedProvisioningMessage::ProtocolVersion
CertificateProvisioning::GetProtocolVersion() {
SignedProvisioningMessage::ProvisioningType
CertificateProvisioning::GetProvisioningType() {
if (crypto_session_->GetPreProvisionTokenType() == kClientTokenOemCert)
return SignedProvisioningMessage::PROVISIONING_30;
else
@@ -291,13 +292,15 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest(
SignedProvisioningMessage signed_provisioning_msg;
signed_provisioning_msg.set_message(serialized_message);
signed_provisioning_msg.set_signature(request_signature);
signed_provisioning_msg.set_protocol_version(GetProtocolVersion());
signed_provisioning_msg.set_provisioning_type(GetProvisioningType());
if (core_message.empty()) {
// OEMCrypto does not support core messages.
supports_core_messages_ = false;
} else {
signed_provisioning_msg.set_oemcrypto_core_message(core_message);
}
signed_provisioning_msg.set_protocol_version(
SignedProvisioningMessage_ProvisioningProtocolVersion_VERSION_1_1);
std::string serialized_request;
signed_provisioning_msg.SerializeToString(&serialized_request);
@@ -393,6 +396,22 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
return CERT_PROVISIONING_RESPONSE_ERROR_4;
}
if (provisioning_response.has_status()) {
if (provisioning_response.status() != ProvisioningResponse::NO_ERROR) {
LOGE("Provisioning Response status: %d", provisioning_response.status());
}
switch (provisioning_response.status()) {
case ProvisioningResponse::NO_ERROR:
break;
case ProvisioningResponse::REVOKED_DEVICE_CREDENTIALS:
case ProvisioningResponse::REVOKED_DEVICE_SERIES:
return DEVICE_REVOKED;
default:
return CERT_PROVISIONING_RESPONSE_ERROR_10;
}
}
CryptoWrappedKey private_key;
const CdmResponseType status = crypto_session_->LoadProvisioning(
signed_message, core_message, signature, &private_key.key());

View File

@@ -471,6 +471,21 @@ message SignedMessage {
optional bytes oemcrypto_core_message = 9;
}
// ----------------------------------------------------------------------------
// hash_algorithm.proto
// ----------------------------------------------------------------------------
// Description of section:
// Public protocol buffer definitions for Widevine Hash Algorithm protocol.
enum HashAlgorithmProto {
// Unspecified hash algorithm: SHA_256 shall be used for ECC based algorithms
// and SHA_1 shall be used otherwise.
HASH_ALGORITHM_UNSPECIFIED = 0;
HASH_ALGORITHM_SHA_1 = 1;
HASH_ALGORITHM_SHA_256 = 2;
HASH_ALGORITHM_SHA_384 = 3;
}
// ----------------------------------------------------------------------------
// certificate_provisioning.proto
// ----------------------------------------------------------------------------
@@ -556,6 +571,15 @@ message ProvisioningResponse {
// Device CA token component of the keybox.
optional bytes device_ca_token = 3;
}
enum ProvisioningStatus {
// Indicates a valid provisioning response
NO_ERROR = 0;
// The device credentials have been revoked. Provisioning is not possible.
REVOKED_DEVICE_CREDENTIALS = 1;
// Devices in this series have been revoked. Provisioning is not possible.
REVOKED_DEVICE_SERIES = 2;
}
// AES-128 encrypted device private RSA key. PKCS#1 ASN.1 DER-encoded.
// Required. For X.509 certificates, the private RSA key may also include
// a prefix as specified by private_key_prefix in the X509CertificateMetadata
@@ -575,6 +599,10 @@ message ProvisioningResponse {
optional bytes wrapping_key = 5;
// Only populated in OTA keybox provisioning response.
optional OtaKeybox ota_keybox = 6;
// The provisioning service may return a ProvisioningStatus. Fields other
// than |status| may be empty and should be ignored if the |status|
// is present and not NO_ERROR
optional ProvisioningStatus status = 7;
}
// Protocol-specific context data used to hold the state of the server in
@@ -607,7 +635,21 @@ message ProvisioningContextKeyData {
// Serialized ProvisioningRequest or ProvisioningResponse signed with
// The message authentication key.
message SignedProvisioningMessage {
enum ProtocolVersion {
enum ProvisioningProtocolVersion {
VERSION_UNSPECIFIED = 0;
VERSION_1 = 1;
// Version 1.1 changed error handling. Some errors are returned as a field
// in a response message rather than being handled as errors via the API
// implementation. E.g. embedded in the ProvisioningResponse rather than
// returning a 400 error to the caller.
VERSION_1_1 = 2;
// Version 2 will implement a larger change of the protocol definition
// in protobufs. This will provide a cleaner separation between protocols.
VERSION_2 = 3;
}
enum ProvisioningType { // This enum was renamed to avoid confusion
PROVISIONING_TYPE_UNSPECIFIED = 0;
SERVICE_CERTIFICATE_REQUEST = 1; // Service certificate request.
PROVISIONING_20 = 2; // Keybox factory-provisioned devices.
PROVISIONING_30 = 3; // OEM certificate factory-provisioned devices.
@@ -624,9 +666,9 @@ message SignedProvisioningMessage {
// response.
optional bytes signature = 2;
// Version number of provisioning protocol.
optional ProtocolVersion protocol_version = 3 [default = PROVISIONING_20];
optional ProvisioningType provisioning_type = 3 [default = PROVISIONING_20];
// Protocol-specific context / state information for multiple-exchange,
// stateful provisioing protocols. Optional.
// stateful provisioning protocols. Optional.
optional SignedProvisioningContext signed_provisioning_context = 4;
// Remote attestation data to authenticate that the ChromeOS client device
// is operating in verified mode. Remote attestation challenge data is
@@ -637,6 +679,10 @@ message SignedProvisioningMessage {
// This field was introduced in OEMCrypto API v16. The core message format is
// documented in the "Widevine Core Message Serialization".
optional bytes oemcrypto_core_message = 6;
// Optional field that indicates the hash algorithm used in signature scheme.
optional HashAlgorithmProto hash_algorithm = 7;
// Indicates which version of the protocol is in use.
optional ProvisioningProtocolVersion protocol_version = 8;
}
// ----------------------------------------------------------------------------

View File

@@ -263,10 +263,11 @@ bool FakeProvisioningServer::MakeResponse(
? "WIDEVINE_DRM"
: "X509");
video_widevine::SignedProvisioningMessage::ProtocolVersion version =
signed_request.protocol_version();
LOGD("Request uses protocol version: %d", version);
if (version != video_widevine::SignedProvisioningMessage::PROVISIONING_20) {
const video_widevine::SignedProvisioningMessage::ProvisioningType
provisioning_type = signed_request.provisioning_type();
LOGD("Request uses provisioning type: %d", provisioning_type);
if (provisioning_type !=
video_widevine::SignedProvisioningMessage::PROVISIONING_20) {
LOGE("Fake provisioning server only handles Keyboxes");
return false;
}
@@ -314,7 +315,7 @@ bool FakeProvisioningServer::MakeResponse(
// Sign the response.
video_widevine::SignedProvisioningMessage signed_response;
signed_response.set_protocol_version(signed_request.protocol_version());
signed_response.set_provisioning_type(signed_request.provisioning_type());
std::string message;
provisioning_response.SerializeToString(&message);
signed_response.set_message(message);

View File

@@ -71,6 +71,10 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
case CERT_PROVISIONING_RESPONSE_ERROR_9:
*os << "CERT_PROVISIONING_RESPONSE_ERROR_9";
break;
case CERT_PROVISIONING_RESPONSE_ERROR_10:
*os << "CERT_PROVISIONING_RESPONSE_ERROR_10";
break;
break;
case CLIENT_ID_AES_ENCRYPT_ERROR:
*os << "CLIENT_ID_AES_ENCRYPT_ERROR";
break;

View File

@@ -76,7 +76,15 @@ const std::vector<std::string> kCanDisableAnalogOutput = {
using video_widevine::LicenseIdentification;
using video_widevine::LicenseRequest_ContentIdentification;
using video_widevine::ProvisioningResponse;
using video_widevine::ProvisioningResponse_ProvisioningStatus;
using video_widevine::ProvisioningResponse_ProvisioningStatus_NO_ERROR;
using video_widevine::
ProvisioningResponse_ProvisioningStatus_REVOKED_DEVICE_CREDENTIALS;
using video_widevine::
ProvisioningResponse_ProvisioningStatus_REVOKED_DEVICE_SERIES;
using video_widevine::SignedProvisioningMessage;
using video_widevine::
SignedProvisioningMessage_ProvisioningProtocolVersion_VERSION_1_1;
// TODO(rfrias): refactor to print out the decryption test names
struct SubSampleInfo {
@@ -2468,6 +2476,113 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningSpoidTest) {
alternate_cdm_id_2_serial_number_1);
}
TEST_F(WvCdmRequestLicenseTest, ProvisioningRevocationTest) {
Unprovision();
CdmResponseType result =
decryptor_->OpenSession(config_.key_system(), nullptr,
kDefaultCdmIdentifier, nullptr, &session_id_);
switch (result) {
case NO_ERROR:
decryptor_->CloseSession(session_id_);
return;
case NEED_PROVISIONING:
break;
default:
EXPECT_EQ(NO_ERROR, result);
return;
}
std::string provisioning_server;
std::string cert_authority, provisioning_request;
result = decryptor_->GetProvisioningRequest(
kCertificateWidevine, cert_authority, kDefaultCdmIdentifier,
kEmptyServiceCertificate, kLevelDefault, &provisioning_request,
&provisioning_server);
EXPECT_EQ(wvcdm::NO_ERROR, result);
if (NO_ERROR != result) return;
EXPECT_EQ(provisioning_server, kDefaultProvisioningServerUrl);
if (!wvcdm::Properties::provisioning_messages_are_binary()) {
std::vector<uint8_t> request = Base64SafeDecode(provisioning_request);
provisioning_request.assign(request.begin(), request.end());
}
// Verify that provisioning request has protocol version set correctly
SignedProvisioningMessage signed_provisioning_msg;
EXPECT_TRUE(signed_provisioning_msg.ParseFromString(provisioning_request));
EXPECT_EQ(SignedProvisioningMessage_ProvisioningProtocolVersion_VERSION_1_1,
signed_provisioning_msg.protocol_version());
const bool supports_core_messages =
signed_provisioning_msg.has_oemcrypto_core_message() &&
!signed_provisioning_msg.oemcrypto_core_message().empty();
// Create provisioning responses with differing ProvisioningStatus values
const std::vector<ProvisioningResponse_ProvisioningStatus>
provisioning_status{
ProvisioningResponse_ProvisioningStatus_NO_ERROR,
ProvisioningResponse_ProvisioningStatus_REVOKED_DEVICE_CREDENTIALS,
ProvisioningResponse_ProvisioningStatus_REVOKED_DEVICE_SERIES,
// Add undefined ProvisioningStatus
static_cast<ProvisioningResponse_ProvisioningStatus>(
ProvisioningResponse_ProvisioningStatus_REVOKED_DEVICE_SERIES +
10)};
// Now form provisioning messages for each of the status values and verify
// that they have been handled correctly
for (ProvisioningResponse_ProvisioningStatus status : provisioning_status) {
result = decryptor_->GetProvisioningRequest(
kCertificateWidevine, cert_authority, kDefaultCdmIdentifier,
kEmptyServiceCertificate, kLevelDefault, &provisioning_request,
&provisioning_server);
EXPECT_EQ(wvcdm::NO_ERROR, result);
if (NO_ERROR != result) return;
EXPECT_EQ(provisioning_server, kDefaultProvisioningServerUrl);
ProvisioningResponse provisioning_response;
provisioning_response.set_status(status);
SignedProvisioningMessage signed_response;
signed_response.set_signature("fake signature");
std::string message;
provisioning_response.SerializeToString(&message);
signed_response.set_message(message);
if (supports_core_messages) {
signed_response.set_oemcrypto_core_message("fake oemcrypto core msg");
}
std::string response;
signed_response.SerializeToString(&response);
if (!wvcdm::Properties::provisioning_messages_are_binary()) {
std::vector<uint8_t> response_vec(response.begin(), response.end());
response = "\"signedResponse\": \"";
response.append(wvcdm::Base64SafeEncode(response_vec));
response.append("\"");
}
std::string cert, wrapped_key;
result = decryptor_->HandleProvisioningResponse(
kDefaultCdmIdentifier, response, kLevelDefault, &cert, &wrapped_key);
switch (status) {
case ProvisioningResponse_ProvisioningStatus_REVOKED_DEVICE_CREDENTIALS:
case ProvisioningResponse_ProvisioningStatus_REVOKED_DEVICE_SERIES:
EXPECT_EQ(DEVICE_REVOKED, result) << "Provisioning status: " << status;
break;
default:
// ProvisioningResponse_ProvisioningStatus_NO_ERROR will not return
// NO_ERROR because signature, oemcrypto core message are fake
EXPECT_NE(DEVICE_REVOKED, result) << "Provisioning status: " << status;
break;
}
}
}
TEST_F(WvCdmRequestLicenseTest, PropertySetTest) {
TestWvCdmClientPropertySet property_set_L1;
TestWvCdmClientPropertySet property_set_L3;

View File

@@ -299,10 +299,11 @@ enum {
kRestoreOfflineLicenseError3 = ERROR_DRM_VENDOR_MIN + 314,
kNoSrmVersion = ERROR_DRM_VENDOR_MIN + 315,
kCertProvisioningResponseError9 = ERROR_DRM_VENDOR_MIN + 316,
kCertProvisioningResponseError10 = ERROR_DRM_VENDOR_MIN + 317,
// This should always follow the last error code.
// The offset value should be updated each time a new error code is added.
kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 316,
kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 317,
// Used by crypto test mode
kErrorTestMode = ERROR_DRM_VENDOR_MAX,

View File

@@ -105,6 +105,8 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) {
return kCertProvisioningResponseError8;
case wvcdm::CERT_PROVISIONING_RESPONSE_ERROR_9:
return kCertProvisioningResponseError9;
case wvcdm::CERT_PROVISIONING_RESPONSE_ERROR_10:
return kCertProvisioningResponseError10;
case wvcdm::CLIENT_IDENTIFICATION_TOKEN_ERROR_1:
return kClientIdentificationTokenError1;
case wvcdm::CLIENT_ID_AES_ENCRYPT_ERROR:

View File

@@ -359,6 +359,7 @@ static Status mapCdmResponseType_1_0(wvcdm::CdmResponseType res) {
case wvcdm::PROVISIONING_NOT_ALLOWED_FOR_ATSC:
case wvcdm::NO_SRM_VERSION:
case wvcdm::CERT_PROVISIONING_RESPONSE_ERROR_9:
case wvcdm::CERT_PROVISIONING_RESPONSE_ERROR_10:
ALOGW("Returns UNKNOWN error for legacy status: %d", res);
return Status::ERROR_DRM_UNKNOWN;
@@ -650,6 +651,11 @@ static S mapCdmResponseType(wvcdm::CdmResponseType res) {
case wvcdm::LOAD_PROVISIONING_ERROR:
err = ::drm::V1_4::Status::PROVISIONING_PARSE_ERROR;
break;
/* TODO (b/180579631): Uncomment when DRM Status type
* PROVISIONING_REQUEST_REJECTED has been created
case wvcdm::CERT_PROVISIONING_RESPONSE_ERROR_10:
err = ::drm::V1_4::Status::PROVISIONING_REQUEST_REJECTED;
*/
case wvcdm::EMPTY_PROVISIONING_CERTIFICATE_1:
case wvcdm::EMPTY_PROVISIONING_CERTIFICATE_2:
err = ::drm::V1_4::Status::RETRYABLE_PROVISIONING_ERROR;