diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 4962d870..f62cd347 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -374,23 +374,38 @@ bool CryptoSession::GetProvisioningId(std::string* provisioning_id) { if (!initialized_) { return false; } - OEMCryptoResult sts; - M_TIME( - sts = OEMCrypto_GetKeyData( - buf, - &buf_size, - requested_security_level_), - metrics_, - oemcrypto_get_key_data_, - sts, - metrics::Pow2Bucket(buf_size), - requested_security_level_); - if (OEMCrypto_SUCCESS != sts) { - return false; - } - provisioning_id->assign(reinterpret_cast(&buf[8]), 16); - return true; + if (pre_provision_token_type_ == kClientTokenOemCert) { + // OEM Cert devices have no provisioning-unique ID embedded in them, so we + // synthesize one by using the External Device-Unique ID and inverting all + // the bits. + if (!GetExternalDeviceUniqueId(provisioning_id)) return false; + + for (size_t i = 0; i < provisioning_id->size(); ++i) { + char value = (*provisioning_id)[i]; + (*provisioning_id)[i] = ~value; + } + + return true; + } else { + OEMCryptoResult sts; + M_TIME( + sts = OEMCrypto_GetKeyData( + buf, + &buf_size, + requested_security_level_), + metrics_, + oemcrypto_get_key_data_, + sts, + metrics::Pow2Bucket(buf_size), + requested_security_level_); + if (OEMCrypto_SUCCESS != sts) { + return false; + } + + provisioning_id->assign(reinterpret_cast(&buf[8]), 16); + return true; + } } uint8_t CryptoSession::GetSecurityPatchLevel() { diff --git a/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h b/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h index 4e283b2c..1aa89a46 100644 --- a/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h +++ b/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h @@ -323,6 +323,7 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener, // On SPOID devices, calling this will seal the CDM Identifier Builder, thus // making it an error to change the origin. status_t getDeviceUniqueId(std::string* id); + status_t getProvisioningUniqueId(std::string* id); const std::string& origin() const { return mCdmIdentifier.origin; } bool set_origin(const std::string& id); diff --git a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp index ab668fa4..bcbe9903 100644 --- a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp @@ -678,7 +678,11 @@ Return WVDrmPlugin::getPropertyByteArray( value = StrToVector(id); } } else if (name == "provisioningUniqueId") { - status = queryProperty(wvcdm::QUERY_KEY_PROVISIONING_ID, value); + std::string id; + status = mCdmIdentifierBuilder.getProvisioningUniqueId(&id); + if (status == android::OK) { + value = StrToVector(id); + } } else if (name == "serviceCertificate") { value = StrToVector(mPropertySet.service_certificate()); } else { @@ -1343,6 +1347,24 @@ status_t WVDrmPlugin::CdmIdentifierBuilder::getDeviceUniqueId(std::string* id) { } } +status_t WVDrmPlugin::CdmIdentifierBuilder::getProvisioningUniqueId(std::string* id) { + if (mUseSpoid) { + // To fake a provisioning-unique ID on SPOID devices where we can't expose + // the real provisioning-unique ID, we just use the SPOID and invert all the + // bits. + status_t res = getDeviceUniqueId(id); + if (res != android::OK) return res; + + for (char& c : *id) { + c = ~c; + } + + return android::OK; + } else { + return mParent.queryProperty(wvcdm::QUERY_KEY_PROVISIONING_ID, *id); + } +} + bool WVDrmPlugin::CdmIdentifierBuilder::set_origin(const std::string& id) { if (mIsIdentifierSealed) return false; mCdmIdentifier.origin = id; diff --git a/libwvdrmengine/src_hidl/WVDrmFactory.cpp b/libwvdrmengine/src_hidl/WVDrmFactory.cpp index be688053..533e0d90 100644 --- a/libwvdrmengine/src_hidl/WVDrmFactory.cpp +++ b/libwvdrmengine/src_hidl/WVDrmFactory.cpp @@ -63,7 +63,6 @@ bool WVDrmFactory::areSpoidsEnabled() { // version is the first if it's a factory ROM. firstApiLevel = property_get_int32("ro.build.version.sdk", 0); } - // TODO(juce): b/34548395 Make sure this API version is correct. return firstApiLevel >= 26; // Android O } diff --git a/libwvdrmengine/test/unit/WVDrmFactory_test.cpp b/libwvdrmengine/test/unit/WVDrmFactory_test.cpp index 4336d979..52fa2bad 100644 --- a/libwvdrmengine/test/unit/WVDrmFactory_test.cpp +++ b/libwvdrmengine/test/unit/WVDrmFactory_test.cpp @@ -104,7 +104,6 @@ TEST(WVDrmFactoryTest, CalculatesSpoidUseCorrectly) { // version is the first if it's a factory ROM. firstApiLevel = property_get_int32("ro.build.version.sdk", 0); } - // TODO(juce): b/34548395 Make sure this API version is correct. bool shouldUseSpoids = (firstApiLevel >= 26); // Android O EXPECT_EQ(shouldUseSpoids, factory.areSpoidsEnabled()) <<