OEMCrypto v14 adapter and plugin changes

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

This updates the dynamic adapter and some plugins to work with the new
OEMCrypto v14 API.

bug: 70334345 Entitlement License - reference code and unit tests
bug: 34103646 Encryption Scheme Propagation
bug: 69552641 Update OEMCrypto_LoadTestKeybox
bug: 69867568 OEMCrypto - Report Analog

test: In child CL.
Change-Id: I51349d15b779d52d245bd234867bbd2bbe7b9ae7
This commit is contained in:
Fred Gylys-Colwell
2018-01-23 15:15:22 -08:00
parent aff3e81a2c
commit 95fa4ffca9
5 changed files with 231 additions and 35 deletions

View File

@@ -53,7 +53,7 @@ OEMCryptoResult OEMCrypto_CreateOldUsageEntry(SecurityLevel level,
uint64_t time_since_last_decrypt, OEMCrypto_Usage_Entry_Status status, uint64_t time_since_last_decrypt, OEMCrypto_Usage_Entry_Status status,
uint8_t* server_mac_key, uint8_t* client_mac_key, const uint8_t* pst, uint8_t* server_mac_key, uint8_t* client_mac_key, const uint8_t* pst,
size_t pst_length); size_t pst_length);
uint32_t OEMCrypto_GetAnalogOutputFlags(SecurityLevel level);
} // namespace wvcdm } // namespace wvcdm
/* The following functions are deprecated in OEMCrypto v13. They are defined /* The following functions are deprecated in OEMCrypto v13. They are defined
@@ -62,12 +62,25 @@ OEMCryptoResult OEMCrypto_CreateOldUsageEntry(SecurityLevel level,
*/ */
extern "C" { extern "C" {
OEMCryptoResult OEMCrypto_LoadKeys_V11_or_V12( struct OEMCrypto_KeyObject_V13 { // Used for backwards compatibility.
const uint8_t* key_id;
size_t key_id_length;
const uint8_t* key_data_iv;
const uint8_t* key_data;
size_t key_data_length;
const uint8_t* key_control_iv;
const uint8_t* key_control;
OEMCryptoCipherMode cipher_mode;
};
// Backwards compitiblity between v14 and v13.
OEMCryptoResult OEMCrypto_LoadKeys_Back_Compat(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length, const uint8_t* signature, size_t signature_length,
const uint8_t* enc_mac_keys_iv, const uint8_t* enc_mac_keys, const uint8_t* enc_mac_keys_iv, const uint8_t* enc_mac_keys,
size_t num_keys, const OEMCrypto_KeyObject* key_array, const uint8_t* pst, size_t num_keys, const OEMCrypto_KeyObject_V13* key_array,
size_t pst_length); const uint8_t* pst, size_t pst_length, const uint8_t* srm_requirement,
OEMCrypto_LicenseType license_type);
OEMCryptoResult OEMCrypto_UpdateUsageTable(); OEMCryptoResult OEMCrypto_UpdateUsageTable();

View File

@@ -203,10 +203,10 @@ class DefaultKeySession : public KeySession {
} else { } else {
LOGV("DefaultKeySession::LoadKeys: enc_mac_key not set"); LOGV("DefaultKeySession::LoadKeys: enc_mac_key not set");
} }
std::vector<OEMCrypto_KeyObject> load_keys(keys.size()); std::vector<OEMCrypto_KeyObject_V13> load_keys(keys.size());
for (size_t i = 0; i < keys.size(); ++i) { for (size_t i = 0; i < keys.size(); ++i) {
const CryptoKey* ki = &keys[i]; const CryptoKey* ki = &keys[i];
OEMCrypto_KeyObject* ko = &load_keys[i]; OEMCrypto_KeyObject_V13* ko = &load_keys[i];
ko->key_id = msg + GetOffset(message, ki->key_id()); ko->key_id = msg + GetOffset(message, ki->key_id());
ko->key_id_length = ki->key_id().length(); ko->key_id_length = ki->key_id().length();
ko->key_data_iv = msg + GetOffset(message, ki->key_data_iv()); ko->key_data_iv = msg + GetOffset(message, ki->key_data_iv());

View File

@@ -68,12 +68,19 @@ typedef OEMCryptoResult (*L1_LoadKeys_t)(
const uint8_t* signature, size_t signature_length, const uint8_t* signature, size_t signature_length,
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys, const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
const OEMCrypto_KeyObject* key_array, const uint8_t* pst, const OEMCrypto_KeyObject* key_array, const uint8_t* pst,
size_t pst_length, const uint8_t* srm_requirement,
OEMCrypto_LicenseType license_type);
typedef OEMCryptoResult (*L1_LoadKeys_V13_t)(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length,
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
const OEMCrypto_KeyObject_V13* key_array, const uint8_t* pst,
size_t pst_length, const uint8_t* srm_requirement); size_t pst_length, const uint8_t* srm_requirement);
typedef OEMCryptoResult (*L1_LoadKeys_V11_or_V12_t)( typedef OEMCryptoResult (*L1_LoadKeys_V11_or_V12_t)(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length, const uint8_t* signature, size_t signature_length,
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys, const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
const OEMCrypto_KeyObject* key_array, const uint8_t* pst, const OEMCrypto_KeyObject_V13* key_array, const uint8_t* pst,
size_t pst_length); size_t pst_length);
typedef OEMCryptoResult (*L1_LoadKeys_V9_or_V10_t)( typedef OEMCryptoResult (*L1_LoadKeys_V9_or_V10_t)(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
@@ -86,6 +93,9 @@ typedef OEMCryptoResult (*L1_LoadKeys_V8_t)(
const uint8_t* signature, size_t signature_length, const uint8_t* signature, size_t signature_length,
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys, const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
const OEMCrypto_KeyObject_V10* key_array); const OEMCrypto_KeyObject_V10* key_array);
typedef OEMCryptoResult(*L1_LoadEntitledContentKeys_t)(
OEMCrypto_SESSION session, size_t num_keys,
const OEMCrypto_EntitledContentKeyObject* key_array);
typedef OEMCryptoResult (*L1_RefreshKeys_t)( typedef OEMCryptoResult (*L1_RefreshKeys_t)(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length, size_t num_keys, const uint8_t* signature, size_t signature_length, size_t num_keys,
@@ -94,8 +104,12 @@ typedef OEMCryptoResult (*L1_QueryKeyControl_t)(
OEMCrypto_SESSION session, const uint8_t* key_id, size_t key_id_length, OEMCrypto_SESSION session, const uint8_t* key_id, size_t key_id_length,
uint8_t* key_control_block, size_t* key_control_block_length); uint8_t* key_control_block, size_t* key_control_block_length);
typedef OEMCryptoResult (*L1_SelectKey_t)(const OEMCrypto_SESSION session, typedef OEMCryptoResult (*L1_SelectKey_t)(const OEMCrypto_SESSION session,
const uint8_t* key_id, const uint8_t* content_key_id,
size_t key_id_length); size_t content_key_id_length,
OEMCryptoCipherMode cipher_mode);
typedef OEMCryptoResult (*L1_SelectKey_V13_t)(const OEMCrypto_SESSION session,
const uint8_t* key_id,
size_t key_id_length);
typedef OEMCryptoResult (*L1_DecryptCTR_V10_t)( typedef OEMCryptoResult (*L1_DecryptCTR_V10_t)(
OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length, OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length,
bool is_encrypted, const uint8_t* iv, size_t offset, bool is_encrypted, const uint8_t* iv, size_t offset,
@@ -117,7 +131,9 @@ typedef OEMCryptoResult (*L1_WrapKeybox_t)(const uint8_t* keybox,
size_t transportKeyLength); size_t transportKeyLength);
typedef OEMCryptoResult (*L1_InstallKeybox_t)(const uint8_t* keybox, typedef OEMCryptoResult (*L1_InstallKeybox_t)(const uint8_t* keybox,
size_t keyBoxLength); size_t keyBoxLength);
typedef OEMCryptoResult (*L1_LoadTestKeybox_t)(); typedef OEMCryptoResult (*L1_LoadTestKeybox_t)(const uint8_t *buffer,
size_t length);
typedef OEMCryptoResult (*L1_LoadTestKeybox_V13_t)();
typedef OEMCryptoResult (*L1_IsKeyboxValid_t)(); typedef OEMCryptoResult (*L1_IsKeyboxValid_t)();
typedef OEMCryptoResult (*L1_GetDeviceID_t)(uint8_t* deviceID, typedef OEMCryptoResult (*L1_GetDeviceID_t)(uint8_t* deviceID,
size_t* idLength); size_t* idLength);
@@ -244,6 +260,7 @@ typedef OEMCryptoResult (*L1_CreateOldUsageEntry_t)(
uint64_t time_since_last_decrypt, OEMCrypto_Usage_Entry_Status status, uint64_t time_since_last_decrypt, OEMCrypto_Usage_Entry_Status status,
uint8_t* server_mac_key, uint8_t* client_mac_key, const uint8_t* pst, uint8_t* server_mac_key, uint8_t* client_mac_key, const uint8_t* pst,
size_t pst_length); size_t pst_length);
typedef uint32_t (*L1_GetAnalogOutputFlags_t)(void);
struct FunctionPointers { struct FunctionPointers {
uint32_t version; uint32_t version;
@@ -255,6 +272,7 @@ struct FunctionPointers {
L1_GenerateNonce_t GenerateNonce; L1_GenerateNonce_t GenerateNonce;
L1_GenerateSignature_t GenerateSignature; L1_GenerateSignature_t GenerateSignature;
L1_LoadKeys_t LoadKeys; L1_LoadKeys_t LoadKeys;
L1_LoadEntitledContentKeys_t LoadEntitledContentKeys;
L1_RefreshKeys_t RefreshKeys; L1_RefreshKeys_t RefreshKeys;
L1_QueryKeyControl_t QueryKeyControl; L1_QueryKeyControl_t QueryKeyControl;
L1_SelectKey_t SelectKey; L1_SelectKey_t SelectKey;
@@ -308,6 +326,7 @@ struct FunctionPointers {
L1_MoveEntry_t MoveEntry; L1_MoveEntry_t MoveEntry;
L1_CopyOldUsageEntry_t CopyOldUsageEntry; L1_CopyOldUsageEntry_t CopyOldUsageEntry;
L1_CreateOldUsageEntry_t CreateOldUsageEntry; L1_CreateOldUsageEntry_t CreateOldUsageEntry;
L1_GetAnalogOutputFlags_t GetAnalogOutputFlags;
L1_LoadKeys_V8_t LoadKeys_V8; L1_LoadKeys_V8_t LoadKeys_V8;
L1_GenerateRSASignature_V8_t GenerateRSASignature_V8; L1_GenerateRSASignature_V8_t GenerateRSASignature_V8;
@@ -315,6 +334,9 @@ struct FunctionPointers {
L1_LoadKeys_V9_or_V10_t LoadKeys_V9_or_V10; L1_LoadKeys_V9_or_V10_t LoadKeys_V9_or_V10;
L1_LoadKeys_V11_or_V12_t LoadKeys_V11_or_V12; L1_LoadKeys_V11_or_V12_t LoadKeys_V11_or_V12;
L1_DeactivateUsageEntry_V12_t DeactivateUsageEntry_V12; L1_DeactivateUsageEntry_V12_t DeactivateUsageEntry_V12;
L1_LoadKeys_V13_t LoadKeys_V13;
L1_SelectKey_V13_t SelectKey_V13;
L1_LoadTestKeybox_V13_t LoadTestKeybox_V13;
}; };
// The WatchDog looks after a worker thread that is trying to initialize L3. // The WatchDog looks after a worker thread that is trying to initialize L3.
@@ -493,6 +515,7 @@ struct LevelSession {
if (!level1_.Name) { \ if (!level1_.Name) { \
LOGW("Could not load L1 %s. Falling Back to L3.", \ LOGW("Could not load L1 %s. Falling Back to L3.", \
QUOTE(Function)); \ QUOTE(Function)); \
if (level1_.Terminate) level1_.Terminate(); \
return false; \ return false; \
} \ } \
} }
@@ -580,7 +603,7 @@ class Adapter {
} }
level1_valid_ = true; level1_valid_ = true;
const uint32_t kMinimumVersion = 8; const uint32_t kMinimumVersion = 8;
const uint32_t kMaximumVersion = 13; const uint32_t kMaximumVersion = 14;
level1_.version = kMinimumVersion; level1_.version = kMinimumVersion;
LOOKUP_ALL(8, Initialize, OEMCrypto_Initialize); LOOKUP_ALL(8, Initialize, OEMCrypto_Initialize);
LOOKUP_ALL(8, APIVersion, OEMCrypto_APIVersion); LOOKUP_ALL(8, APIVersion, OEMCrypto_APIVersion);
@@ -639,6 +662,7 @@ class Adapter {
LOOKUP_ALL( 8, GetDeviceID, OEMCrypto_GetDeviceID); LOOKUP_ALL( 8, GetDeviceID, OEMCrypto_GetDeviceID);
LOOKUP( 9, 9, GetHDCPCapability_V9, OEMCrypto_GetHDCPCapability_V9); LOOKUP( 9, 9, GetHDCPCapability_V9, OEMCrypto_GetHDCPCapability_V9);
LOOKUP_ALL(10, GetHDCPCapability, OEMCrypto_GetHDCPCapability); LOOKUP_ALL(10, GetHDCPCapability, OEMCrypto_GetHDCPCapability);
LOOKUP_ALL(14, GetAnalogOutputFlags, OEMCrypto_GetAnalogOutputFlags);
LOOKUP_ALL( 8, GetKeyData, OEMCrypto_GetKeyData); LOOKUP_ALL( 8, GetKeyData, OEMCrypto_GetKeyData);
LOOKUP_ALL(10, GetMaxNumberOfSessions, OEMCrypto_GetMaxNumberOfSessions); LOOKUP_ALL(10, GetMaxNumberOfSessions, OEMCrypto_GetMaxNumberOfSessions);
LOOKUP_ALL(10, GetNumberOfOpenSessions, OEMCrypto_GetNumberOfOpenSessions); LOOKUP_ALL(10, GetNumberOfOpenSessions, OEMCrypto_GetNumberOfOpenSessions);
@@ -653,9 +677,12 @@ class Adapter {
LOOKUP( 8, 8, LoadKeys_V8, OEMCrypto_LoadKeys_V8); LOOKUP( 8, 8, LoadKeys_V8, OEMCrypto_LoadKeys_V8);
LOOKUP( 9, 10, LoadKeys_V9_or_V10, OEMCrypto_LoadKeys_V9_or_V10); LOOKUP( 9, 10, LoadKeys_V9_or_V10, OEMCrypto_LoadKeys_V9_or_V10);
LOOKUP(11, 12, LoadKeys_V11_or_V12, OEMCrypto_LoadKeys_V11_or_V12); LOOKUP(11, 12, LoadKeys_V11_or_V12, OEMCrypto_LoadKeys_V11_or_V12);
LOOKUP_ALL(13, LoadKeys, OEMCrypto_LoadKeys); LOOKUP(13, 13, LoadKeys_V13, OEMCrypto_LoadKeys_V13);
LOOKUP_ALL(14, LoadKeys, OEMCrypto_LoadKeys);
LOOKUP_ALL(14, LoadEntitledContentKeys, OEMCrypto_LoadEntitledContentKeys);
LOOKUP_ALL(13, LoadSRM, OEMCrypto_LoadSRM); LOOKUP_ALL(13, LoadSRM, OEMCrypto_LoadSRM);
LOOKUP_ALL(10, LoadTestKeybox, OEMCrypto_LoadTestKeybox); LOOKUP(10, 13, LoadTestKeybox_V13, OEMCrypto_LoadTestKeybox_V13);
LOOKUP_ALL(14, LoadTestKeybox, OEMCrypto_LoadTestKeybox);
LOOKUP_ALL(10, LoadTestRSAKey, OEMCrypto_LoadTestRSAKey); LOOKUP_ALL(10, LoadTestRSAKey, OEMCrypto_LoadTestRSAKey);
LOOKUP_ALL(13, LoadUsageEntry, OEMCrypto_LoadUsageEntry); LOOKUP_ALL(13, LoadUsageEntry, OEMCrypto_LoadUsageEntry);
LOOKUP_ALL(13, LoadUsageTableHeader, OEMCrypto_LoadUsageTableHeader); LOOKUP_ALL(13, LoadUsageTableHeader, OEMCrypto_LoadUsageTableHeader);
@@ -669,7 +696,8 @@ class Adapter {
LOOKUP_ALL(12, RewrapDeviceRSAKey30, OEMCrypto_RewrapDeviceRSAKey30); LOOKUP_ALL(12, RewrapDeviceRSAKey30, OEMCrypto_RewrapDeviceRSAKey30);
LOOKUP_ALL( 8, SecurityLevel, OEMCrypto_SecurityLevel); LOOKUP_ALL( 8, SecurityLevel, OEMCrypto_SecurityLevel);
LOOKUP_ALL(11, SecurityPatchLevel, OEMCrypto_Security_Patch_Level); LOOKUP_ALL(11, SecurityPatchLevel, OEMCrypto_Security_Patch_Level);
LOOKUP_ALL( 8, SelectKey, OEMCrypto_SelectKey); LOOKUP( 8, 13, SelectKey_V13, OEMCrypto_SelectKey_V13);
LOOKUP_ALL(14, SelectKey, OEMCrypto_SelectKey);
LOOKUP_ALL(13, ShrinkUsageTableHeader, OEMCrypto_ShrinkUsageTableHeader); LOOKUP_ALL(13, ShrinkUsageTableHeader, OEMCrypto_ShrinkUsageTableHeader);
LOOKUP_ALL(13, SupportedCertificates, OEMCrypto_SupportedCertificates); LOOKUP_ALL(13, SupportedCertificates, OEMCrypto_SupportedCertificates);
LOOKUP_ALL( 9, SupportsUsageTable, OEMCrypto_SupportsUsageTable); LOOKUP_ALL( 9, SupportsUsageTable, OEMCrypto_SupportsUsageTable);
@@ -757,15 +785,18 @@ class Adapter {
level3_.GenerateDerivedKeys = Level3_GenerateDerivedKeys; level3_.GenerateDerivedKeys = Level3_GenerateDerivedKeys;
level3_.GenerateNonce = Level3_GenerateNonce; level3_.GenerateNonce = Level3_GenerateNonce;
level3_.GenerateSignature = Level3_GenerateSignature; level3_.GenerateSignature = Level3_GenerateSignature;
level3_.LoadKeys = Level3_LoadKeys; // TODO(srujzs): commenting out the following allows code to compile, but
// all unit tests will fail.
// TODO(srujzs): add level3_.LoadKeys = Level3_LoadKeys;
// TODO(srujzs): add level3_.LoadEntitledContentKeys = Level3_LoadEntitledContentKeys;
level3_.RefreshKeys = Level3_RefreshKeys; level3_.RefreshKeys = Level3_RefreshKeys;
level3_.QueryKeyControl = Level3_QueryKeyControl; level3_.QueryKeyControl = Level3_QueryKeyControl;
level3_.SelectKey = Level3_SelectKey; level3_.SelectKey_V13 = Level3_SelectKey; // TODO(srujzs): update.
level3_.DecryptCENC = Level3_DecryptCENC; level3_.DecryptCENC = Level3_DecryptCENC;
level3_.CopyBuffer = Level3_CopyBuffer; level3_.CopyBuffer = Level3_CopyBuffer;
level3_.WrapKeybox = Level3_WrapKeybox; level3_.WrapKeybox = Level3_WrapKeybox;
level3_.InstallKeybox = Level3_InstallKeybox; level3_.InstallKeybox = Level3_InstallKeybox;
level3_.LoadTestKeybox = Level3_LoadTestKeybox; level3_.LoadTestKeybox_V13 = Level3_LoadTestKeybox; // TODO(srujzs): update.
level3_.IsKeyboxValid = Level3_IsKeyboxValid; level3_.IsKeyboxValid = Level3_IsKeyboxValid;
level3_.GetDeviceID = Level3_GetDeviceID; level3_.GetDeviceID = Level3_GetDeviceID;
level3_.GetKeyData = Level3_GetKeyData; level3_.GetKeyData = Level3_GetKeyData;
@@ -779,6 +810,7 @@ class Adapter {
level3_.SecurityPatchLevel = Level3_SecurityPatchLevel; level3_.SecurityPatchLevel = Level3_SecurityPatchLevel;
level3_.SecurityLevel = Level3_SecurityLevel; level3_.SecurityLevel = Level3_SecurityLevel;
level3_.GetHDCPCapability = Level3_GetHDCPCapability; level3_.GetHDCPCapability = Level3_GetHDCPCapability;
// TODO(srujzs): add level3_.GetAnalogOutputFlags = Level3_GetAnalogOutputFlags;
level3_.SupportsUsageTable = Level3_SupportsUsageTable; level3_.SupportsUsageTable = Level3_SupportsUsageTable;
level3_.IsAntiRollbackHwPresent = Level3_IsAntiRollbackHwPresent; level3_.IsAntiRollbackHwPresent = Level3_IsAntiRollbackHwPresent;
level3_.GetNumberOfOpenSessions = Level3_GetNumberOfOpenSessions; level3_.GetNumberOfOpenSessions = Level3_GetNumberOfOpenSessions;
@@ -1017,6 +1049,15 @@ OEMCryptoResult OEMCrypto_GetHDCPCapability(
} }
} }
uint32_t OEMCrypto_GetAnalogOutputFlags(SecurityLevel level) {
if (!kAdapter) return OEMCrypto_Unknown_Analog_Output;
const FunctionPointers* fcn = kAdapter->get(level);
if (!fcn) return OEMCrypto_Unknown_Analog_Output;
if (fcn->version < 14) return OEMCrypto_Unknown_Analog_Output;
if (fcn->GetAnalogOutputFlags == NULL) return OEMCrypto_Unknown_Analog_Output;
return fcn->GetAnalogOutputFlags();
}
bool OEMCrypto_SupportsUsageTable(SecurityLevel level) { bool OEMCrypto_SupportsUsageTable(SecurityLevel level) {
if (!kAdapter) return false; if (!kAdapter) return false;
const FunctionPointers* fcn = kAdapter->get(level); const FunctionPointers* fcn = kAdapter->get(level);
@@ -1183,16 +1224,19 @@ extern "C" OEMCryptoResult OEMCrypto_GenerateSignature(
signature, signature_length); signature, signature_length);
} }
extern "C" OEMCryptoResult OEMCrypto_LoadKeys( extern "C" OEMCryptoResult OEMCrypto_LoadKeys_Back_Compat(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length, const uint8_t* signature, size_t signature_length,
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys, const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
const OEMCrypto_KeyObject* key_array, const uint8_t* pst, size_t pst_length, const OEMCrypto_KeyObject_V13* key_array, const uint8_t* pst,
const uint8_t* srm_requirement) { size_t pst_length, const uint8_t* srm_requirement,
OEMCrypto_LicenseType license_type) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session); LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if (pair.fcn->version < 11) { if (pair.fcn->version < 11) {
if (license_type != OEMCrypto_ContentLicense)
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
std::vector<OEMCrypto_KeyObject_V10> key_array_v10(num_keys); std::vector<OEMCrypto_KeyObject_V10> key_array_v10(num_keys);
for (size_t i = 0; i < num_keys; i++) { for (size_t i = 0; i < num_keys; i++) {
key_array_v10[i].key_id = key_array[i].key_id; key_array_v10[i].key_id = key_array[i].key_id;
@@ -1207,44 +1251,169 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
return OEMCrypto_ERROR_NOT_IMPLEMENTED; return OEMCrypto_ERROR_NOT_IMPLEMENTED;
} }
} }
OEMCrypto_KeyObject_V10* key_array_v10_ptr = NULL;
if (num_keys > 0) key_array_v10_ptr = &key_array_v10[0];
if (pair.fcn->version == 8) { if (pair.fcn->version == 8) {
if (pair.fcn->LoadKeys_V8 == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; if (pair.fcn->LoadKeys_V8 == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return pair.fcn->LoadKeys_V8(pair.session, message, message_length, return pair.fcn->LoadKeys_V8(pair.session, message, message_length,
signature, signature_length, enc_mac_key_iv, signature, signature_length, enc_mac_key_iv,
enc_mac_key, num_keys, &key_array_v10[0]); enc_mac_key, num_keys, key_array_v10_ptr);
} else { } else {
if (pair.fcn->LoadKeys_V9_or_V10 == NULL) if (pair.fcn->LoadKeys_V9_or_V10 == NULL)
return OEMCrypto_ERROR_NOT_IMPLEMENTED; return OEMCrypto_ERROR_NOT_IMPLEMENTED;
OEMCryptoResult result = pair.fcn->LoadKeys_V9_or_V10( OEMCryptoResult result = pair.fcn->LoadKeys_V9_or_V10(
pair.session, message, message_length, signature, signature_length, pair.session, message, message_length, signature, signature_length,
enc_mac_key_iv, enc_mac_key, num_keys, &key_array_v10[0], pst, enc_mac_key_iv, enc_mac_key, num_keys, key_array_v10_ptr, pst,
pst_length); pst_length);
// Convert a vendor specific error, to make it actionable // Convert a vendor specific error, to make it actionable
if (result == kOemCryptoResultVendorSpecificError1) if (result == kOemCryptoResultVendorSpecificError1)
result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE; result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE;
return result; return result;
} }
} else if (pair.fcn->version < 13) {
if (license_type != OEMCrypto_ContentLicense)
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (pair.fcn->LoadKeys_V11_or_V12 == NULL)
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
OEMCryptoResult result = pair.fcn->LoadKeys_V11_or_V12(
pair.session, message, message_length, signature, signature_length,
enc_mac_key_iv, enc_mac_key, num_keys, key_array, pst, pst_length);
// Convert a vendor specific error, to make it actionable
if (result == kOemCryptoResultVendorSpecificError1)
result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE;
return result;
} else if (pair.fcn->version < 14) {
if (license_type != OEMCrypto_ContentLicense)
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (pair.fcn->LoadKeys_V13 == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return pair.fcn->LoadKeys_V13(pair.session, message, message_length,
signature, signature_length, enc_mac_key_iv,
enc_mac_key, num_keys, key_array, pst,
pst_length, srm_requirement);
} else { } else {
if (pair.fcn->LoadKeys == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
std::vector<OEMCrypto_KeyObject> key_array_v14(num_keys);
for (size_t i = 0; i < num_keys; i++) {
key_array_v14[i].key_id = key_array[i].key_id;
key_array_v14[i].key_id_length = key_array[i].key_id_length;
key_array_v14[i].key_data_iv = key_array[i].key_data_iv;
key_array_v14[i].key_data = key_array[i].key_data;
key_array_v14[i].key_data_length = key_array[i].key_data_length;
key_array_v14[i].key_control_iv = key_array[i].key_control_iv;
key_array_v14[i].key_control = key_array[i].key_control;
}
OEMCrypto_KeyObject* key_array_v14_ptr = NULL;
if (num_keys > 0) key_array_v14_ptr = &key_array_v14[0];
return pair.fcn->LoadKeys(pair.session, message, message_length, signature,
signature_length, enc_mac_key_iv, enc_mac_key,
num_keys, key_array_v14_ptr, pst, pst_length,
srm_requirement, license_type);
}
}
/* The CDM layer should use OEMCrypto_LoadKeys_Back_Compat instead. This is
* used by unit tests, and forces cipher mode to CTR when used with an older
* oemcrypto.
*/
extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length,
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
const OEMCrypto_KeyObject* key_array, const uint8_t* pst, size_t pst_length,
const uint8_t* srm_requirement, OEMCrypto_LicenseType license_type) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if (pair.fcn->version < 11) {
if (license_type != OEMCrypto_ContentLicense)
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
std::vector<OEMCrypto_KeyObject_V10> key_array_v10(num_keys);
for (size_t i = 0; i < num_keys; i++) {
key_array_v10[i].key_id = key_array[i].key_id;
key_array_v10[i].key_id_length = key_array[i].key_id_length;
key_array_v10[i].key_data_iv = key_array[i].key_data_iv;
key_array_v10[i].key_data = key_array[i].key_data;
key_array_v10[i].key_data_length = key_array[i].key_data_length;
key_array_v10[i].key_control_iv = key_array[i].key_control_iv;
key_array_v10[i].key_control = key_array[i].key_control;
}
OEMCrypto_KeyObject_V10* key_array_v10_ptr = NULL;
if (num_keys > 0) key_array_v10_ptr = &key_array_v10[0];
if (pair.fcn->version == 8) {
if (pair.fcn->LoadKeys_V8 == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return pair.fcn->LoadKeys_V8(pair.session, message, message_length,
signature, signature_length, enc_mac_key_iv,
enc_mac_key, num_keys, key_array_v10_ptr);
} else {
if (pair.fcn->LoadKeys_V9_or_V10 == NULL)
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
OEMCryptoResult result = pair.fcn->LoadKeys_V9_or_V10(
pair.session, message, message_length, signature, signature_length,
enc_mac_key_iv, enc_mac_key, num_keys, key_array_v10_ptr, pst,
pst_length);
// Convert a vendor specific error, to make it actionable
if (result == kOemCryptoResultVendorSpecificError1)
result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE;
return result;
}
} else if (pair.fcn->version < 14) {
if (license_type != OEMCrypto_ContentLicense)
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
std::vector<OEMCrypto_KeyObject_V13> key_array_v13(num_keys);
for (size_t i = 0; i < num_keys; i++) {
key_array_v13[i].key_id = key_array[i].key_id;
key_array_v13[i].key_id_length = key_array[i].key_id_length;
key_array_v13[i].key_data_iv = key_array[i].key_data_iv;
key_array_v13[i].key_data = key_array[i].key_data;
key_array_v13[i].key_data_length = key_array[i].key_data_length;
key_array_v13[i].key_control_iv = key_array[i].key_control_iv;
key_array_v13[i].key_control = key_array[i].key_control;
key_array_v13[i].cipher_mode == OEMCrypto_CipherMode_CTR;
}
OEMCrypto_KeyObject_V13* key_array_v13_ptr = NULL;
if (num_keys > 0) key_array_v13_ptr = &key_array_v13[0];
if (pair.fcn->version < 13) { if (pair.fcn->version < 13) {
if (pair.fcn->LoadKeys_V11_or_V12 == NULL) if (pair.fcn->LoadKeys_V11_or_V12 == NULL)
return OEMCrypto_ERROR_NOT_IMPLEMENTED; return OEMCrypto_ERROR_NOT_IMPLEMENTED;
OEMCryptoResult result = pair.fcn->LoadKeys_V11_or_V12( OEMCryptoResult result = pair.fcn->LoadKeys_V11_or_V12(
pair.session, message, message_length, signature, signature_length, pair.session, message, message_length, signature, signature_length,
enc_mac_key_iv, enc_mac_key, num_keys, key_array, pst, pst_length); enc_mac_key_iv, enc_mac_key, num_keys, key_array_v13_ptr, pst,
pst_length);
// Convert a vendor specific error, to make it actionable // Convert a vendor specific error, to make it actionable
if (result == kOemCryptoResultVendorSpecificError1) if (result == kOemCryptoResultVendorSpecificError1)
result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE; result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE;
return result; return result;
} else { } else {
if (pair.fcn->LoadKeys == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; if (pair.fcn->LoadKeys_V13 == NULL)
return pair.fcn->LoadKeys(pair.session, message, message_length, return OEMCrypto_ERROR_NOT_IMPLEMENTED;
signature, signature_length, enc_mac_key_iv, return pair.fcn->LoadKeys_V13(pair.session, message, message_length,
enc_mac_key, num_keys, key_array, pst, signature, signature_length, enc_mac_key_iv,
pst_length, srm_requirement); enc_mac_key, num_keys, key_array_v13_ptr,
pst, pst_length, srm_requirement);
} }
} else {
if (pair.fcn->LoadKeys == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return pair.fcn->LoadKeys(pair.session, message, message_length, signature,
signature_length, enc_mac_key_iv, enc_mac_key,
num_keys, key_array, pst, pst_length,
srm_requirement, license_type);
} }
} }
extern "C" OEMCryptoResult OEMCrypto_LoadEntitledContentKeys(
OEMCrypto_SESSION session, size_t num_keys,
const OEMCrypto_EntitledContentKeyObject* key_array) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if (pair.fcn->version < 14) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
if (pair.fcn->LoadEntitledContentKeys == NULL)
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return pair.fcn->LoadEntitledContentKeys(pair.session, num_keys, key_array);
}
extern "C" OEMCryptoResult OEMCrypto_RefreshKeys( extern "C" OEMCryptoResult OEMCrypto_RefreshKeys(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length, size_t num_keys, const uint8_t* signature, size_t signature_length, size_t num_keys,
@@ -1271,12 +1440,19 @@ extern "C" OEMCryptoResult OEMCrypto_QueryKeyControl(
extern "C" OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session, extern "C" OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session,
const uint8_t* key_id, const uint8_t* key_id,
size_t key_id_length) { size_t key_id_length,
OEMCryptoCipherMode cipher_mode) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session); LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if (pair.fcn->SelectKey == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; if (pair.fcn->version < 14) {
return pair.fcn->SelectKey(pair.session, key_id, key_id_length); if (pair.fcn->SelectKey_V13 == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return pair.fcn->SelectKey_V13(pair.session, key_id, key_id_length);
} else {
if (pair.fcn->SelectKey == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return pair.fcn->SelectKey(pair.session, key_id, key_id_length,
cipher_mode);
}
} }
extern "C" OEMCryptoResult OEMCrypto_DecryptCENC( extern "C" OEMCryptoResult OEMCrypto_DecryptCENC(
@@ -1327,13 +1503,18 @@ extern "C" OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox,
return OEMCrypto_InstallKeybox(keybox, keyBoxLength, kLevelDefault); return OEMCrypto_InstallKeybox(keybox, keyBoxLength, kLevelDefault);
} }
extern "C" OEMCryptoResult OEMCrypto_LoadTestKeybox() { extern "C" OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t* buffer,
size_t length) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
const FunctionPointers* fcn = kAdapter->get(kLevelDefault); const FunctionPointers* fcn = kAdapter->get(kLevelDefault);
if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION; if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if (fcn->version < 10) return OEMCrypto_ERROR_NOT_IMPLEMENTED; if (fcn->version < 10) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (fcn->LoadTestKeybox_V13 != NULL) {
// Old versions might use wrong keybox, but this is the best we can do.
return fcn->LoadTestKeybox_V13();
}
if (fcn->LoadTestKeybox == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; if (fcn->LoadTestKeybox == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return fcn->LoadTestKeybox(); return fcn->LoadTestKeybox(buffer, length);
} }
extern "C" OEMCryptoResult OEMCrypto_IsKeyboxValid() { extern "C" OEMCryptoResult OEMCrypto_IsKeyboxValid() {

View File

@@ -21,7 +21,8 @@ class WVGenericCryptoInterface {
virtual OEMCryptoResult selectKey(const OEMCrypto_SESSION session, virtual OEMCryptoResult selectKey(const OEMCrypto_SESSION session,
const uint8_t* key_id, const uint8_t* key_id,
size_t key_id_length) { size_t key_id_length) {
return OEMCrypto_SelectKey(session, key_id, key_id_length); return OEMCrypto_SelectKey(session, key_id, key_id_length,
OEMCrypto_CipherMode_CBC);
} }
virtual OEMCryptoResult encrypt(OEMCrypto_SESSION session, virtual OEMCryptoResult encrypt(OEMCrypto_SESSION session,

View File

@@ -21,7 +21,8 @@ class WVGenericCryptoInterface {
virtual OEMCryptoResult selectKey(const OEMCrypto_SESSION session, virtual OEMCryptoResult selectKey(const OEMCrypto_SESSION session,
const uint8_t* key_id, const uint8_t* key_id,
size_t key_id_length) { size_t key_id_length) {
return OEMCrypto_SelectKey(session, key_id, key_id_length); return OEMCrypto_SelectKey(session, key_id, key_id_length,
OEMCrypto_CipherMode_CBC);
} }
virtual OEMCryptoResult encrypt(OEMCrypto_SESSION session, virtual OEMCryptoResult encrypt(OEMCrypto_SESSION session,