OEMCrypto v12 Haystack and Adapter
Merge of several CLs from the widevine repo. Merge from widevine repo of http://go/wvgerrit/22440 Build OEMCrypto v12 Haystacks with cache flush level3/mips/libwvlevel3.a Level3 Library 4465 Nov 29 2016 13:34:45 level3/arm/libwvlevel3.a Level3 Library 4445 Nov 29 2016 14:02:08 level3/x86/libwvlevel3.a Level3 Library 4464 Nov 29 2016 14:22:21 Merge from widevine repo of http://go/wvgerrit/22403 Pull cache flush out of Haystack Merge from widevine repo of http://go/wvgerrit/21145 OEMCrypto v12 stubs -- just the header file changes. Merge from widevine repo of http://go/wvgerrit/21146 Add OEMCrypto v12 functions to profiler This CL adds the new oemcrypto v12 functions for provision 3.0 to the list of profiler functions. Merge from widevine repo of http://go/wvgerrit/21143 OEMCrypto v12 adapter This CL updates the oemcrypto dynamic and static adpaters to include oemcrypto v12 funtionality. It adds the three new Provisioning 3.0 functions. It also adds code in the initialization routine to null out all of the function pointers if any of them fail to load. It is better to fall back to level 3 than to use an inconsistent level 1. b/31528025 Change-Id: I3579dc93e00ad7e7c743beecdd8291eac557d4e4
This commit is contained in:
@@ -35,6 +35,8 @@ OEMCryptoResult OEMCrypto_GetNumberOfOpenSessions(SecurityLevel level,
|
||||
OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(SecurityLevel level,
|
||||
size_t* maximum);
|
||||
uint8_t OEMCrypto_Security_Patch_Level(SecurityLevel level);
|
||||
OEMCrypto_ProvisioningMethod OEMCrypto_GetProvisioningMethod(
|
||||
SecurityLevel level);
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_OEMCRYPTO_ADAPTER_H_
|
||||
|
||||
@@ -188,6 +188,21 @@ typedef OEMCryptoResult (*L1_DeleteUsageEntry_t)(
|
||||
typedef OEMCryptoResult (*L1_ForceDeleteUsageEntry_t)(const uint8_t* pst,
|
||||
size_t pst_length);
|
||||
typedef OEMCryptoResult (*L1_DeleteUsageTable_t)();
|
||||
typedef OEMCrypto_ProvisioningMethod (*L1_GetProvisioningMethod_t)();
|
||||
typedef OEMCryptoResult (*L1_GetOEMPublicCertificate_t)(
|
||||
OEMCrypto_SESSION session,
|
||||
uint8_t *public_cert,
|
||||
size_t *public_cert_length);
|
||||
typedef OEMCryptoResult (*L1_RewrapDeviceRSAKey30_t)(
|
||||
OEMCrypto_SESSION session,
|
||||
const uint32_t *nonce,
|
||||
const uint8_t* encrypted_message_key,
|
||||
size_t encrypted_message_key_length,
|
||||
const uint8_t* enc_rsa_key,
|
||||
size_t enc_rsa_key_length,
|
||||
const uint8_t* enc_rsa_key_iv,
|
||||
uint8_t* wrapped_rsa_key,
|
||||
size_t* wrapped_rsa_key_length);
|
||||
|
||||
struct FunctionPointers {
|
||||
uint32_t version;
|
||||
@@ -235,6 +250,9 @@ struct FunctionPointers {
|
||||
L1_DeleteUsageEntry_t DeleteUsageEntry;
|
||||
L1_ForceDeleteUsageEntry_t ForceDeleteUsageEntry;
|
||||
L1_DeleteUsageTable_t DeleteUsageTable;
|
||||
L1_GetProvisioningMethod_t GetProvisioningMethod;
|
||||
L1_GetOEMPublicCertificate_t GetOEMPublicCertificate;
|
||||
L1_RewrapDeviceRSAKey30_t RewrapDeviceRSAKey30;
|
||||
|
||||
L1_LoadKeys_V8_t LoadKeys_V8;
|
||||
L1_GenerateRSASignature_V8_t GenerateRSASignature_V8;
|
||||
@@ -245,7 +263,7 @@ struct FunctionPointers {
|
||||
// The Cache Flush function is very processor dependent, but is needed by the
|
||||
// haystack code. The haystack code is delivered as a static prebuilt library.
|
||||
// For that reason, we pass a function pointer for cache_flush into the
|
||||
// haystack. The function is combiled outside of the haystack and may use
|
||||
// haystack. The function is compiled outside of the haystack and may use
|
||||
// target (processor) specific compiler flags.
|
||||
void clear_cache_function(void *page, size_t len) {
|
||||
|
||||
@@ -309,7 +327,7 @@ struct LevelSession {
|
||||
level1_.Name = (L1_##Name##_t)dlsym(level1_library_, QUOTE(Function)); \
|
||||
if (!level1_.Name) { \
|
||||
LOGW("Could not load L1 %s. Falling Back to L3.", \
|
||||
QUOTE(OEMCrypto_##Name)); \
|
||||
QUOTE(Function)); \
|
||||
return false; \
|
||||
}
|
||||
|
||||
@@ -331,7 +349,14 @@ class Adapter {
|
||||
|
||||
OEMCryptoResult Initialize() {
|
||||
LoadLevel3();
|
||||
std::string base_path;
|
||||
wvcdm::Properties::GetDeviceFilesBasePath(wvcdm::kSecurityLevelL3,
|
||||
&base_path);
|
||||
bool is_in_app = Level3_IsInApp(base_path.c_str());
|
||||
OEMCryptoResult result = Level3_Initialize(clear_cache_function);
|
||||
if (is_in_app) {
|
||||
return result;
|
||||
}
|
||||
if (force_level3()) {
|
||||
LOGW("Test code. User requested falling back to L3");
|
||||
return result;
|
||||
@@ -350,6 +375,7 @@ class Adapter {
|
||||
if (LoadLevel1()) {
|
||||
LOGD("OEMCrypto_Initialize Level 1 success. I will use level 1.");
|
||||
} else {
|
||||
level1_ = FunctionPointers(); // revert to all null pointers.
|
||||
dlclose(level1_library_);
|
||||
level1_library_ = NULL;
|
||||
level1_valid_ = false;
|
||||
@@ -402,7 +428,7 @@ class Adapter {
|
||||
if (level1_.version == 8) {
|
||||
LOOKUP(LoadKeys_V8, OEMCrypto_LoadKeys_V8);
|
||||
LOOKUP(GenerateRSASignature_V8, OEMCrypto_GenerateRSASignature_V8);
|
||||
} else {
|
||||
} else { // version >= 9
|
||||
LOOKUP(GenerateRSASignature, OEMCrypto_GenerateRSASignature);
|
||||
LOOKUP(SupportsUsageTable, OEMCrypto_SupportsUsageTable);
|
||||
LOOKUP(UpdateUsageTable, OEMCrypto_UpdateUsageTable);
|
||||
@@ -413,7 +439,7 @@ class Adapter {
|
||||
if (level1_.version == 9) {
|
||||
LOOKUP(LoadKeys_V9_or_V10, OEMCrypto_LoadKeys_V9_or_V10);
|
||||
LOOKUP(GetHDCPCapability_V9, OEMCrypto_GetHDCPCapability_V9);
|
||||
} else {
|
||||
} else { // version >= 10.
|
||||
LOOKUP(LoadTestKeybox, OEMCrypto_LoadTestKeybox);
|
||||
LOOKUP(LoadTestRSAKey, OEMCrypto_LoadTestRSAKey);
|
||||
LOOKUP(QueryKeyControl, OEMCrypto_QueryKeyControl);
|
||||
@@ -426,16 +452,29 @@ class Adapter {
|
||||
if (level1_.version == 10) {
|
||||
LOOKUP(LoadKeys_V9_or_V10, OEMCrypto_LoadKeys_V9_or_V10);
|
||||
LOOKUP(DecryptCTR_V10, OEMCrypto_DecryptCTR_V10);
|
||||
} else { // version 11.
|
||||
} else { // version >= 11.
|
||||
LOOKUP(LoadKeys, OEMCrypto_LoadKeys);
|
||||
LOOKUP(DecryptCENC, OEMCrypto_DecryptCENC);
|
||||
LOOKUP(SecurityPatchLevel, OEMCrypto_Security_Patch_Level);
|
||||
if (level1_.version >= 12) {
|
||||
LOOKUP(GetProvisioningMethod, OEMCrypto_GetProvisioningMethod);
|
||||
LOOKUP(GetOEMPublicCertificate, OEMCrypto_GetOEMPublicCertificate);
|
||||
LOOKUP(RewrapDeviceRSAKey30, OEMCrypto_RewrapDeviceRSAKey30);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If we have a valid keybox, initialization is done. We're good.
|
||||
if (OEMCrypto_SUCCESS == level1_.IsKeyboxValid()) {
|
||||
return true;
|
||||
}
|
||||
// If we use provisioning 3.0, initialization is done. We may not
|
||||
// be good, but there's no reason to try loading a keybox. Any errors
|
||||
// will have to be caught in the future when provisioning fails.
|
||||
if (level1_.version > 11 &&
|
||||
(level1_.GetProvisioningMethod() == OEMCrypto_OEMCertificate)) {
|
||||
return true;
|
||||
}
|
||||
uint8_t buffer[1];
|
||||
size_t buffer_size = 0;
|
||||
if (OEMCrypto_ERROR_NOT_IMPLEMENTED == level1_.GetKeyData(buffer,
|
||||
@@ -522,6 +561,9 @@ class Adapter {
|
||||
level3_.DeleteUsageEntry = Level3_DeleteUsageEntry;
|
||||
level3_.ForceDeleteUsageEntry = Level3_ForceDeleteUsageEntry;
|
||||
level3_.DeleteUsageTable = Level3_DeleteUsageTable;
|
||||
level3_.GetProvisioningMethod = Level3_GetProvisioningMethod;
|
||||
level3_.GetOEMPublicCertificate = Level3_GetOEMPublicCertificate;
|
||||
level3_.RewrapDeviceRSAKey30 = Level3_RewrapDeviceRSAKey30;
|
||||
|
||||
level3_.version = Level3_APIVersion();
|
||||
}
|
||||
@@ -658,6 +700,17 @@ OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox,
|
||||
return fcn->InstallKeybox(keybox, keyBoxLength);
|
||||
}
|
||||
|
||||
OEMCrypto_ProvisioningMethod OEMCrypto_GetProvisioningMethod(
|
||||
SecurityLevel level) {
|
||||
oemprofiler::ProfiledScope ps(
|
||||
oemprofiler::OEM_FUNCTION_GET_PROVISIONING_METHOD);
|
||||
if (!kAdapter) return OEMCrypto_ProvisioningError;
|
||||
const FunctionPointers* fcn = kAdapter->get(level);
|
||||
if (!fcn) return OEMCrypto_ProvisioningError;
|
||||
if (fcn->version < 12) return OEMCrypto_Keybox;
|
||||
return fcn->GetProvisioningMethod();
|
||||
}
|
||||
|
||||
OEMCryptoResult OEMCrypto_IsKeyboxValid(SecurityLevel level) {
|
||||
|
||||
oemprofiler::ProfiledScope ps(oemprofiler::OEM_FUNCTION_IS_KEYBOX_VALID);
|
||||
@@ -1024,6 +1077,24 @@ extern "C" OEMCryptoResult OEMCrypto_IsKeyboxValid() {
|
||||
return OEMCrypto_IsKeyboxValid(kLevelDefault);
|
||||
}
|
||||
|
||||
extern "C" OEMCrypto_ProvisioningMethod OEMCrypto_GetProvisioningMethod() {
|
||||
return OEMCrypto_GetProvisioningMethod(kLevelDefault);
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(
|
||||
OEMCrypto_SESSION session,
|
||||
uint8_t *public_cert,
|
||||
size_t *public_cert_length) {
|
||||
wvcdm::oemprofiler::ProfiledScope ps(
|
||||
wvcdm::oemprofiler::OEM_FUNCTION_GET_OEM_PUBLIC_CERTIFICATE);
|
||||
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
LevelSession pair = kAdapter->get(session);
|
||||
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
if (pair.fcn->version < 12) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
return pair.fcn->GetOEMPublicCertificate(pair.session, public_cert,
|
||||
public_cert_length);
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID,
|
||||
size_t* idLength) {
|
||||
return OEMCrypto_GetDeviceID(deviceID, idLength, kLevelDefault);
|
||||
@@ -1046,6 +1117,30 @@ extern "C" OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData,
|
||||
return fcn->GetRandom(randomData, dataLength);
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
|
||||
OEMCrypto_SESSION session,
|
||||
const uint32_t *nonce,
|
||||
const uint8_t* encrypted_message_key,
|
||||
size_t encrypted_message_key_length,
|
||||
const uint8_t* enc_rsa_key,
|
||||
size_t enc_rsa_key_length,
|
||||
const uint8_t* enc_rsa_key_iv,
|
||||
uint8_t* wrapped_rsa_key,
|
||||
size_t* wrapped_rsa_key_length) {
|
||||
wvcdm::oemprofiler::ProfiledScope ps(
|
||||
wvcdm::oemprofiler::OEM_FUNCTION_REWRAP_DEVICE_RSA_KEY_30);
|
||||
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
LevelSession pair = kAdapter->get(session);
|
||||
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
if (pair.fcn->version < 12) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
return pair.fcn->RewrapDeviceRSAKey30(session, nonce, encrypted_message_key,
|
||||
encrypted_message_key_length,
|
||||
enc_rsa_key, enc_rsa_key_length,
|
||||
enc_rsa_key_iv, wrapped_rsa_key,
|
||||
wrapped_rsa_key_length);
|
||||
}
|
||||
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(
|
||||
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||
const uint8_t* signature, size_t signature_length, const uint32_t* nonce,
|
||||
|
||||
@@ -48,6 +48,9 @@ enum OEM_FUNCTION {
|
||||
OEM_FUNCTION_DELETE_USAGE_ENTRY,
|
||||
OEM_FUNCTION_FORCE_DELETE_USAGE_ENTRY,
|
||||
OEM_FUNCTION_DELETE_USAGE_TABLE,
|
||||
OEM_FUNCTION_GET_PROVISIONING_METHOD,
|
||||
OEM_FUNCTION_GET_OEM_PUBLIC_CERTIFICATE,
|
||||
OEM_FUNCTION_REWRAP_DEVICE_RSA_KEY_30,
|
||||
|
||||
OEM_FUNCTION_TESTING, // dummy value for testing purposes
|
||||
OEM_FUNCTION_COUNT
|
||||
|
||||
Reference in New Issue
Block a user