Define Provisioning-Unique ID for New Device IDs
(This is a merge of wvgerrit/25583) Devices that use Provisioning 3.0 did not have a Provisioning-Unique ID defined. Attempting to retrieve it would result in an error. Devices that use SPOIDs with keyboxes would expose the keybox's real Provisioning-Unique ID when asked. This is a security flaw. To solve both cases, an alternative Provisioning-Unique ID is used, consisting of the Device-Unique ID bitwise-inverted. Bug: 36065223 Test: run_all_unit_tests.sh Change-Id: I32512a3e11403e679939187e156904a57a9e24ef
This commit is contained in:
@@ -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<char*>(&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<char*>(&buf[8]), 16);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t CryptoSession::GetSecurityPatchLevel() {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -678,7 +678,11 @@ Return<void> 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;
|
||||
|
||||
Reference in New Issue
Block a user