Use InstallRootKeyCertificate for keybox and cert

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

This CL allows provisioning 3.0 devices to install their OEM certs
from an initialization partition.  This method is already used for
keyboxes on Android -- we are just adding the ability to use it for
OEM certs, also.

Also, for v15, we require OEMCrypto to report a valid certificate in
the unit tests.

bug: 111725154
test: unit tests
Change-Id: I142c84a1a67bdb4cee943cfd12a632421901eb24
This commit is contained in:
Fred Gylys-Colwell
2018-09-02 13:22:53 -07:00
parent 3a2d291dc5
commit 562c14b5f1
6 changed files with 298 additions and 278 deletions

View File

@@ -370,81 +370,87 @@ typedef enum OEMCrypto_ProvisioningMethod {
/*
* Obfuscation Renames.
*/
#define OEMCrypto_Initialize _oecc01
#define OEMCrypto_Terminate _oecc02
#define OEMCrypto_InstallKeybox _oecc03
#define OEMCrypto_InstallRootKeyCertificate _oecc03
#define OEMCrypto_GetKeyData _oecc04
#define OEMCrypto_IsKeyboxValid _oecc05
#define OEMCrypto_IsRootKeyCertificateValid _oecc05
#define OEMCrypto_GetRandom _oecc06
#define OEMCrypto_GetDeviceID _oecc07
#define OEMCrypto_WrapKeybox _oecc08
#define OEMCrypto_WrapRootKeyCertificate _oecc08
#define OEMCrypto_OpenSession _oecc09
#define OEMCrypto_CloseSession _oecc10
#define OEMCrypto_DecryptCTR_V10 _oecc11
#define OEMCrypto_GenerateDerivedKeys _oecc12
#define OEMCrypto_GenerateSignature _oecc13
#define OEMCrypto_GenerateNonce _oecc14
#define OEMCrypto_LoadKeys_V8 _oecc15
#define OEMCrypto_RefreshKeys _oecc16
#define OEMCrypto_SelectKey_V13 _oecc17
#define OEMCrypto_RewrapDeviceRSAKey _oecc18
#define OEMCrypto_LoadDeviceRSAKey _oecc19
#define OEMCrypto_GenerateRSASignature_V8 _oecc20
#define OEMCrypto_DeriveKeysFromSessionKey _oecc21
#define OEMCrypto_APIVersion _oecc22
#define OEMCrypto_SecurityLevel _oecc23
#define OEMCrypto_Generic_Encrypt _oecc24
#define OEMCrypto_Generic_Decrypt _oecc25
#define OEMCrypto_Generic_Sign _oecc26
#define OEMCrypto_Generic_Verify _oecc27
#define OEMCrypto_GetHDCPCapability_V9 _oecc28
#define OEMCrypto_SupportsUsageTable _oecc29
#define OEMCrypto_UpdateUsageTable _oecc30
#define OEMCrypto_DeactivateUsageEntry_V12 _oecc31
#define OEMCrypto_ReportUsage _oecc32
#define OEMCrypto_DeleteUsageEntry _oecc33
#define OEMCrypto_DeleteOldUsageTable _oecc34
#define OEMCrypto_LoadKeys_V9_or_V10 _oecc35
#define OEMCrypto_GenerateRSASignature _oecc36
#define OEMCrypto_GetMaxNumberOfSessions _oecc37
#define OEMCrypto_GetNumberOfOpenSessions _oecc38
#define OEMCrypto_IsAntiRollbackHwPresent _oecc39
#define OEMCrypto_CopyBuffer _oecc40
#define OEMCrypto_QueryKeyControl _oecc41
#define OEMCrypto_LoadTestKeybox_V13 _oecc42
#define OEMCrypto_ForceDeleteUsageEntry _oecc43
#define OEMCrypto_GetHDCPCapability _oecc44
#define OEMCrypto_LoadTestRSAKey _oecc45
#define OEMCrypto_Security_Patch_Level _oecc46
#define OEMCrypto_LoadKeys_V11_or_V12 _oecc47
#define OEMCrypto_DecryptCENC _oecc48
#define OEMCrypto_GetProvisioningMethod _oecc49
#define OEMCrypto_GetOEMPublicCertificate _oecc50
#define OEMCrypto_RewrapDeviceRSAKey30 _oecc51
#define OEMCrypto_SupportedCertificates _oecc52
#define OEMCrypto_IsSRMUpdateSupported _oecc53
#define OEMCrypto_GetCurrentSRMVersion _oecc54
#define OEMCrypto_LoadSRM _oecc55
#define OEMCrypto_LoadKeys_V13 _oecc56
#define OEMCrypto_RemoveSRM _oecc57
#define OEMCrypto_CreateUsageTableHeader _oecc61
#define OEMCrypto_LoadUsageTableHeader _oecc62
#define OEMCrypto_CreateNewUsageEntry _oecc63
#define OEMCrypto_LoadUsageEntry _oecc64
#define OEMCrypto_UpdateUsageEntry _oecc65
#define OEMCrypto_DeactivateUsageEntry _oecc66
#define OEMCrypto_ShrinkUsageTableHeader _oecc67
#define OEMCrypto_MoveEntry _oecc68
#define OEMCrypto_CopyOldUsageEntry _oecc69
#define OEMCrypto_CreateOldUsageEntry _oecc70
#define OEMCrypto_GetAnalogOutputFlags _oecc71
#define OEMCrypto_LoadTestKeybox _oecc78
#define OEMCrypto_LoadEntitledContentKeys _oecc79
#define OEMCrypto_SelectKey _oecc81
#define OEMCrypto_LoadKeys _oecc82
#define OEMCrypto_Initialize _oecc01
#define OEMCrypto_Terminate _oecc02
#define OEMCrypto_InstallKeybox _oecc03
// Rename InstallKeybox to InstallKeyboxOrOEMCert.
#define OEMCrypto_InstallRootKeyCertificate _oecc03
#define OEMCrypto_InstallKeyboxOrOEMCert _oecc03
#define OEMCrypto_GetKeyData _oecc04
#define OEMCrypto_IsKeyboxValid _oecc05
// Rename IsKeyboxValid to IsKeyboxOrOEMCertValid.
#define OEMCrypto_IsRootKeyCertificateValid _oecc05
#define OEMCrypto_IsKeyboxOrOEMCertValid _oecc05
#define OEMCrypto_GetRandom _oecc06
#define OEMCrypto_GetDeviceID _oecc07
#define OEMCrypto_WrapKeybox _oecc08
// Rename WrapKeybox to WrapKeyboxOrOEMCert
#define OEMCrypto_WrapRootKeyCertificate _oecc08
#define OEMCrypto_WrapKeyboxOrOEMCert _oecc08
#define OEMCrypto_OpenSession _oecc09
#define OEMCrypto_CloseSession _oecc10
#define OEMCrypto_DecryptCTR_V10 _oecc11
#define OEMCrypto_GenerateDerivedKeys _oecc12
#define OEMCrypto_GenerateSignature _oecc13
#define OEMCrypto_GenerateNonce _oecc14
#define OEMCrypto_LoadKeys_V8 _oecc15
#define OEMCrypto_RefreshKeys _oecc16
#define OEMCrypto_SelectKey_V13 _oecc17
#define OEMCrypto_RewrapDeviceRSAKey _oecc18
#define OEMCrypto_LoadDeviceRSAKey _oecc19
#define OEMCrypto_GenerateRSASignature_V8 _oecc20
#define OEMCrypto_DeriveKeysFromSessionKey _oecc21
#define OEMCrypto_APIVersion _oecc22
#define OEMCrypto_SecurityLevel _oecc23
#define OEMCrypto_Generic_Encrypt _oecc24
#define OEMCrypto_Generic_Decrypt _oecc25
#define OEMCrypto_Generic_Sign _oecc26
#define OEMCrypto_Generic_Verify _oecc27
#define OEMCrypto_GetHDCPCapability_V9 _oecc28
#define OEMCrypto_SupportsUsageTable _oecc29
#define OEMCrypto_UpdateUsageTable _oecc30
#define OEMCrypto_DeactivateUsageEntry_V12 _oecc31
#define OEMCrypto_ReportUsage _oecc32
#define OEMCrypto_DeleteUsageEntry _oecc33
#define OEMCrypto_DeleteOldUsageTable _oecc34
#define OEMCrypto_LoadKeys_V9_or_V10 _oecc35
#define OEMCrypto_GenerateRSASignature _oecc36
#define OEMCrypto_GetMaxNumberOfSessions _oecc37
#define OEMCrypto_GetNumberOfOpenSessions _oecc38
#define OEMCrypto_IsAntiRollbackHwPresent _oecc39
#define OEMCrypto_CopyBuffer _oecc40
#define OEMCrypto_QueryKeyControl _oecc41
#define OEMCrypto_LoadTestKeybox_V13 _oecc42
#define OEMCrypto_ForceDeleteUsageEntry _oecc43
#define OEMCrypto_GetHDCPCapability _oecc44
#define OEMCrypto_LoadTestRSAKey _oecc45
#define OEMCrypto_Security_Patch_Level _oecc46
#define OEMCrypto_LoadKeys_V11_or_V12 _oecc47
#define OEMCrypto_DecryptCENC _oecc48
#define OEMCrypto_GetProvisioningMethod _oecc49
#define OEMCrypto_GetOEMPublicCertificate _oecc50
#define OEMCrypto_RewrapDeviceRSAKey30 _oecc51
#define OEMCrypto_SupportedCertificates _oecc52
#define OEMCrypto_IsSRMUpdateSupported _oecc53
#define OEMCrypto_GetCurrentSRMVersion _oecc54
#define OEMCrypto_LoadSRM _oecc55
#define OEMCrypto_LoadKeys_V13 _oecc56
#define OEMCrypto_RemoveSRM _oecc57
#define OEMCrypto_CreateUsageTableHeader _oecc61
#define OEMCrypto_LoadUsageTableHeader _oecc62
#define OEMCrypto_CreateNewUsageEntry _oecc63
#define OEMCrypto_LoadUsageEntry _oecc64
#define OEMCrypto_UpdateUsageEntry _oecc65
#define OEMCrypto_DeactivateUsageEntry _oecc66
#define OEMCrypto_ShrinkUsageTableHeader _oecc67
#define OEMCrypto_MoveEntry _oecc68
#define OEMCrypto_CopyOldUsageEntry _oecc69
#define OEMCrypto_CreateOldUsageEntry _oecc70
#define OEMCrypto_GetAnalogOutputFlags _oecc71
#define OEMCrypto_LoadTestKeybox _oecc78
#define OEMCrypto_LoadEntitledContentKeys _oecc79
#define OEMCrypto_SelectKey _oecc81
#define OEMCrypto_LoadKeys _oecc82
/*
* OEMCrypto_Initialize
@@ -1498,7 +1504,7 @@ OEMCryptoResult OEMCrypto_CopyBuffer(const uint8_t* data_addr,
uint8_t subsample_flags);
/*
* OEMCrypto_WrapRootKeyCertificate
* OEMCrypto_WrapKeyboxOrOEMCert
*
* Description:
*
@@ -1507,13 +1513,13 @@ OEMCryptoResult OEMCrypto_CopyBuffer(const uint8_t* data_addr,
* manufacturing, the root of trust should be encrypted with the OEM root key
* and stored on the file system in a region that will not be erased during
* factory reset. This function may be used by legacy systems that use the
* two-step WrapRootKeyCertificate/InstallRootKeyCertificate approach. When
* two-step WrapKeyboxOrOEMCert/InstallKeyboxOrOEMCert approach. When
* the Widevine DRM plugin initializes, it will look for a wrapped root of
* trust in the file /factory/wv.keys and install it into the security
* processor by calling OEMCrypto_InstallRootKeyCertificate().
* processor by calling OEMCrypto_InstallKeyboxOrOEMCert().
*
* OEMCrypto_WrapRootKeyCertificate() is used to generate an OEM-encrypted
* root of trust that may be passed to OEMCrypto_InstallRootKeyCertificate()
* OEMCrypto_WrapKeyboxOrOEMCert() is used to generate an OEM-encrypted
* root of trust that may be passed to OEMCrypto_InstallKeyboxOrOEMCert()
* for provisioning. The root of trust may be either passed in the clear or
* previously encrypted with a transport key. If a transport key is supplied,
* the keybox is first decrypted with the transport key before being wrapped
@@ -1548,14 +1554,14 @@ OEMCryptoResult OEMCrypto_CopyBuffer(const uint8_t* data_addr,
* Version:
* This method is supported by all API versions.
*/
OEMCryptoResult OEMCrypto_WrapRootKeyCertificate(const uint8_t* rot, size_t rotLength,
OEMCryptoResult OEMCrypto_WrapKeyboxOrOEMCert(const uint8_t* rot, size_t rotLength,
uint8_t* wrappedRot,
size_t* wrappedRotLength,
const uint8_t* transportKey,
size_t transportKeyLength);
/*
* OEMCrypto_InstallRootKeyCertificate
* OEMCrypto_InstallKeyboxOrOEMCert
*
* Description:
*
@@ -1564,7 +1570,7 @@ OEMCryptoResult OEMCrypto_WrapRootKeyCertificate(const uint8_t* rot, size_t rotL
* function is called from the Widevine DRM plugin at initialization time if
* there is no valid root of trust installed. It looks for wrapped data in
* the file /factory/wv.keys and if it is present, will read the file and call
* OEMCrypto_InstallRootKeyCertificate() with the contents of the file. This
* OEMCrypto_InstallKeyboxOrOEMCert() with the contents of the file. This
* function is only needed if the factory provisioning method involves saving
* the keybox to the file system.
*
@@ -1585,7 +1591,7 @@ OEMCryptoResult OEMCrypto_WrapRootKeyCertificate(const uint8_t* rot, size_t rotL
* Version:
* This method is supported in all API versions.
*/
OEMCryptoResult OEMCrypto_InstallRootKeyCertificate(const uint8_t* rot,
OEMCryptoResult OEMCrypto_InstallKeyboxOrOEMCert(const uint8_t* rot,
size_t rotLength);
/*
@@ -1681,7 +1687,7 @@ OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(OEMCrypto_SESSION session,
OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t *buffer, size_t length);
/*
* OEMCrypto_IsRootKeyCertificateValid
* OEMCrypto_IsKeyboxOrOEMCertValid
*
* Description:
*
@@ -1713,7 +1719,7 @@ OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t *buffer, size_t length);
* Version:
* This method is supported by all API versions.
*/
OEMCryptoResult OEMCrypto_IsRootKeyCertificateValid(void);
OEMCryptoResult OEMCrypto_IsKeyboxOrOEMCertValid(void);
/*
* OEMCrypto_GetDeviceID

View File

@@ -548,12 +548,10 @@ extern "C" OEMCryptoResult OEMCrypto_CopyBuffer(
return crypto_engine->PushDestination(out_buffer, subsample_flags);
}
extern "C" OEMCryptoResult OEMCrypto_WrapKeybox(const uint8_t* keybox,
size_t keyBoxLength,
uint8_t* wrappedKeybox,
size_t* wrappedKeyBoxLength,
const uint8_t* transportKey,
size_t transportKeyLength) {
extern "C" OEMCryptoResult OEMCrypto_WrapKeyboxOrOEMCert(
const uint8_t* keybox, size_t keyBoxLength, uint8_t* wrappedKeybox,
size_t* wrappedKeyBoxLength, const uint8_t* transportKey,
size_t transportKeyLength) {
if (crypto_engine->config_provisioning_method() != OEMCrypto_Keybox) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
@@ -567,10 +565,10 @@ extern "C" OEMCryptoResult OEMCrypto_WrapKeybox(const uint8_t* keybox,
return OEMCrypto_SUCCESS;
}
extern "C" OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox,
size_t keyBoxLength) {
extern "C" OEMCryptoResult OEMCrypto_InstallKeyboxOrOEMCert(
const uint8_t* keybox, size_t keyBoxLength) {
if (!crypto_engine) {
LOGE("OEMCrypto_InstallKeybox: OEMCrypto Not Initialized.");
LOGE("OEMCrypto_InstallKeyboxOrOEMCert: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (crypto_engine->config_provisioning_method() != OEMCrypto_Keybox) {
@@ -595,23 +593,34 @@ extern "C" OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t* buffer,
return OEMCrypto_SUCCESS;
}
extern "C" OEMCryptoResult OEMCrypto_IsKeyboxValid(void) {
extern "C" OEMCryptoResult OEMCrypto_IsKeyboxOrOEMCertValid(void) {
if (!crypto_engine) {
LOGE("OEMCrypto_IsKeyboxValid: OEMCrypto Not Initialized.");
LOGE("OEMCrypto_IsKeyboxOrOEMCertValid: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (crypto_engine->config_provisioning_method() != OEMCrypto_Keybox) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
switch (crypto_engine->ValidateKeybox()) {
case NO_ERROR:
switch (crypto_engine->config_provisioning_method()) {
case OEMCrypto_DrmCertificate:
return OEMCrypto_SUCCESS;
case BAD_CRC:
return OEMCrypto_ERROR_BAD_CRC;
case BAD_MAGIC:
return OEMCrypto_ERROR_BAD_MAGIC;
case OEMCrypto_Keybox:
switch (crypto_engine->ValidateKeybox()) {
case NO_ERROR:
return OEMCrypto_SUCCESS;
case BAD_CRC:
return OEMCrypto_ERROR_BAD_CRC;
case BAD_MAGIC:
return OEMCrypto_ERROR_BAD_MAGIC;
default:
case OTHER_ERROR:
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
break;
case OEMCrypto_OEMCertificate:
// TODO(fredgc): verify that the certificate exists and is valid.
return OEMCrypto_SUCCESS;
break;
default:
case OTHER_ERROR:
LOGE("Invalid provisioning method: %d.",
crypto_engine->config_provisioning_method());
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
}

View File

@@ -143,6 +143,7 @@ std::string DeviceFeatures::RestrictFilter(const std::string& initial_filter) {
if (api_version < 12) FilterOut(&filter, "*API12*");
if (api_version < 13) FilterOut(&filter, "*API13*");
if (api_version < 14) FilterOut(&filter, "*API14*");
if (api_version < 15) FilterOut(&filter, "*API15*");
// Some tests may require root access. If user is not root, filter these tests
// out.
if (getuid()) {

View File

@@ -538,6 +538,11 @@ TEST_F(OEMCryptoProv30Test, DeviceClaimsOEMCertificate) {
ASSERT_EQ(OEMCrypto_OEMCertificate, OEMCrypto_GetProvisioningMethod());
}
// The OEM certificate must be valid.
TEST_F(OEMCryptoProv30Test, CertValidAPI15) {
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxOrOEMCertValid());
}
TEST_F(OEMCryptoProv30Test, OEMCertValid) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());