Use GetDeviceID to determine SPOID's unique id

Merge from Widevine repo of http://go/wvgerrit/45940

Since the Level 3 OEMCrypto is being updated to Provisioning 3.0, its
SPOID would be derived from its OEM Certificate, breaking backwards
compatibility. This CL changes how we determine what unique id to use
for SPOIDs by checking to see if OEMCrypto_GetDeviceID is implemented,
and if so, using the id returned from that call. If not and the root
of trust is an OEM Cert, we continue to use that OEM Cert.

This allows Level 3 devices to keep the same SPOID when they undergo a
field update to Provisioning 3.0.

Also, the Level 3 OEMCrypto will share a single OEM certificate across
all devices with the same architecture.  Since the OEM Cert is not
unique, it cannot be used to derive a unique id.  By using the unique
id returned by OEMCrypto_GetDeviceID, we can generate a unique SPOID.

The id from OEMCrypto_GetDeviceID has always been required to be
unique for devices with keyboxes.  The functionality and use of this
function for Provisioning 3.0 devices was introduced in OEMCrypto API
version 14.1.

Test: tested as part of http://go/ag/4674759

Change-Id: I65af8246c9312c75c570a2d518caa3de633007c4
This commit is contained in:
Fred Gylys-Colwell
2018-07-01 20:50:32 -07:00
parent de8d11b8de
commit b62a8f1652

View File

@@ -358,21 +358,32 @@ bool CryptoSession::GetInternalDeviceUniqueId(std::string* device_id) {
return false;
}
if (pre_provision_token_type_ == kClientTokenOemCert) {
std::vector<uint8_t> id;
size_t id_length = 32;
id.resize(id_length);
OEMCryptoResult sts =
OEMCrypto_GetDeviceID(&id[0], &id_length, requested_security_level_);
// Increment the count of times this method was called.
metrics_->oemcrypto_get_device_id_.Increment(sts);
if (sts == OEMCrypto_ERROR_SHORT_BUFFER) {
id.resize(id_length);
sts = OEMCrypto_GetDeviceID(&id[0], &id_length, requested_security_level_);
metrics_->oemcrypto_get_device_id_.Increment(sts);
}
if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED &&
pre_provision_token_type_ == kClientTokenOemCert) {
return GetTokenFromOemCert(device_id);
} else {
// Device's authentication root is a keybox.
// Or not. If no keybox, let the OEMCrypto call fail.
std::vector<uint8_t> id;
size_t id_length = 32;
id.resize(id_length);
OEMCryptoResult sts =
OEMCrypto_GetDeviceID(&id[0], &id_length, requested_security_level_);
// Increment the count of times this method was called.
metrics_->oemcrypto_get_device_id_.Increment(sts);
// Either the authentication root is a keybox or the device has transitioned
// to using OEMCerts.
// OEMCryptos, like the Level 3, that transition from Provisioning 2.0 to
// 3.0 would have a new device ID, which would affect SPOID calculation.
// In order to resolve this, we use OEMCrypto_GetDeviceID if it is
// implemented, so the OEMCrypto can continue to report the same device ID.
if (OEMCrypto_SUCCESS != sts) {
// If there is no device ID to be reported, let the call fail.
return false;
}
@@ -389,7 +400,13 @@ bool CryptoSession::GetExternalDeviceUniqueId(std::string* device_id) {
std::string temp;
if (!GetInternalDeviceUniqueId(&temp)) return false;
if (pre_provision_token_type_ == kClientTokenOemCert) {
size_t id_length = 0;
OEMCryptoResult sts =
OEMCrypto_GetDeviceID(NULL, &id_length, requested_security_level_);
metrics_->oemcrypto_get_device_id_.Increment(sts);
if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED &&
pre_provision_token_type_ == kClientTokenOemCert) {
// To keep the size of the value passed back to the application down, hash
// the large OEM Public Cert to a smaller value.
uint8_t hash[SHA256_DIGEST_LENGTH];