Allow OEMCrypto v8 or v9

From Widevine CL:
https://widevine-internal-review.googlesource.com/#/c/9184/

This is some shim code that will load either an OEMCrypto
version 8 or version 9 library.  This should allow us
to test and run stable devices until all OEM's have
updated to version 9.

Android Level 3 library versions are:
level3/mips/libwvlevel3.a  Level3 Library Feb 27 2014 18:18:34
level3/x86/libwvlevel3.a  Level3 Library Feb 27 2014 18:22:14
level3/arm/libwvlevel3.a  Level3 Library Feb 27 2014 12:31:29

Change-Id: I82911e3b4d9056cf3c3ab2b47194fe81ac2776d9
This commit is contained in:
Fred Gylys-Colwell
2014-03-14 15:56:15 -07:00
parent 71e9cacfe2
commit ba6b5c293a
6 changed files with 200 additions and 11 deletions

View File

@@ -34,6 +34,7 @@ OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox,
SecurityLevel level);
uint32_t OEMCrypto_APIVersion(SecurityLevel level);
const char* OEMCrypto_SecurityLevel(SecurityLevel level);
bool OEMCrypto_SupportsUsageTable(SecurityLevel level);
} // namespace wvcdm
#endif // OEMCRYPTO_ADAPTER_H_

View File

@@ -50,6 +50,11 @@ typedef OEMCryptoResult (*L1_LoadKeys_t)(
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);
typedef OEMCryptoResult (*L1_LoadKeys_V8_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* key_array);
typedef OEMCryptoResult (*L1_RefreshKeys_t)(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length, size_t num_keys,
@@ -91,6 +96,11 @@ typedef OEMCryptoResult (*L1_GenerateRSASignature_t)(OEMCrypto_SESSION session,
uint8_t* signature,
size_t* signature_length,
RSA_Padding_Scheme padding_scheme);
typedef OEMCryptoResult (*L1_GenerateRSASignature_V8_t)(OEMCrypto_SESSION session,
const uint8_t* message,
size_t message_length,
uint8_t* signature,
size_t* signature_length);
typedef OEMCryptoResult (*L1_DeriveKeysFromSessionKey_t)(
OEMCrypto_SESSION session, const uint8_t* enc_session_key,
size_t enc_session_key_length, const uint8_t* mac_key_context,
@@ -118,8 +128,28 @@ typedef OEMCryptoResult (*L1_Generic_Verify_t)(OEMCrypto_SESSION session,
size_t signature_length);
typedef uint32_t (*L1_APIVersion_t)();
typedef const char* (*L1_SecurityLevel_t)();
typedef OEMCryptoResult (*L1_GetHDCPCapability_t)(OEMCrypto_HDCP_Capability *current,
OEMCrypto_HDCP_Capability *maximum);
typedef bool (*L1_SupportsUsageTable_t)();
typedef OEMCryptoResult (*L1_UpdateUsageTable_t)();
typedef OEMCryptoResult (*L1_DeactivateUsageEntry_t)(const uint8_t *pst,
size_t pst_length);
typedef OEMCryptoResult (*L1_ReportUsage_t)(OEMCrypto_SESSION session,
const uint8_t *pst,
size_t pst_length,
OEMCrypto_PST_Report *buffer,
size_t *buffer_length);
typedef OEMCryptoResult (*L1_DeleteUsageEntry_t)(OEMCrypto_SESSION session,
const uint8_t* pst,
size_t pst_length,
const uint8_t *message,
size_t message_length,
const uint8_t *signature,
size_t signature_length);
typedef OEMCryptoResult (*L1_DeleteUsageTable_t)();
struct FunctionPointers {
uint32_t version;
L1_Initialize_t Initialize;
L1_Terminate_t Terminate;
L1_OpenSession_t OpenSession;
@@ -147,6 +177,16 @@ struct FunctionPointers {
L1_Generic_Decrypt_t Generic_Decrypt;
L1_Generic_Sign_t Generic_Sign;
L1_Generic_Verify_t Generic_Verify;
L1_GetHDCPCapability_t GetHDCPCapability;
L1_SupportsUsageTable_t SupportsUsageTable;
L1_UpdateUsageTable_t UpdateUsageTable;
L1_DeactivateUsageEntry_t DeactivateUsageEntry;
L1_ReportUsage_t ReportUsage;
L1_DeleteUsageEntry_t DeleteUsageEntry;
L1_DeleteUsageTable_t DeleteUsageTable;
L1_LoadKeys_V8_t LoadKeys_V8;
L1_GenerateRSASignature_V8_t GenerateRSASignature_V8;
};
struct LevelSession {
@@ -240,13 +280,25 @@ class Adapter {
LOGW("Could not initialize L1. Falling Back to L3.");
return false;
}
uint32_t level1_version = level1_.APIVersion();
uint32_t minimum_version = 8; // TODO(fredgc): allow version 8 and 9?
if (level1_version < minimum_version) {
level1_.version = level1_.APIVersion();
uint32_t minimum_version = 8;
if (level1_.version < minimum_version) {
LOGW("liboemcrypto.so is version %d, not %d. Falling Back to L3.",
level1_version, minimum_version);
level1_.version, minimum_version);
return false;
}
if( level1_.version == 8 ) {
LOOKUP(LoadKeys_V8, OEMCrypto_LoadKeys);
LOOKUP(GenerateRSASignature_V8, OEMCrypto_GenerateRSASignature);
} else {
LOOKUP(GetHDCPCapability, OEMCrypto_GetHDCPCapability);
LOOKUP(SupportsUsageTable, OEMCrypto_SupportsUsageTable);
LOOKUP(UpdateUsageTable, OEMCrypto_UpdateUsageTable);
LOOKUP(DeactivateUsageEntry, OEMCrypto_DeactivateUsageEntry);
LOOKUP(ReportUsage, OEMCrypto_ReportUsage);
LOOKUP(DeleteUsageEntry, OEMCrypto_DeleteUsageEntry);
LOOKUP(DeleteUsageTable, OEMCrypto_DeleteUsageTable);
}
if (OEMCrypto_SUCCESS == level1_.IsKeyboxValid()) {
return true;
}
@@ -300,6 +352,14 @@ class Adapter {
level3_.Generic_Encrypt = Level3_Generic_Encrypt;
level3_.Generic_Sign = Level3_Generic_Sign;
level3_.Generic_Verify = Level3_Generic_Verify;
level3_.GetHDCPCapability = Level3_GetHDCPCapability;
level3_.SupportsUsageTable = Level3_SupportsUsageTable;
level3_.UpdateUsageTable = Level3_UpdateUsageTable;
level3_.DeactivateUsageEntry = Level3_DeactivateUsageEntry;
level3_.ReportUsage = Level3_ReportUsage;
level3_.DeleteUsageEntry = Level3_DeleteUsageEntry;
level3_.DeleteUsageTable = Level3_DeleteUsageTable;
level3_.version = Level3_APIVersion();
}
OEMCryptoResult Terminate() {
@@ -447,9 +507,15 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
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);
if (pair.fcn->version == 8) {
return pair.fcn->LoadKeys_V8(pair.session, message, message_length, signature,
signature_length, enc_mac_key_iv, enc_mac_key,
num_keys, key_array);
} else {
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);
}
}
extern "C" OEMCryptoResult OEMCrypto_RefreshKeys(
@@ -587,9 +653,14 @@ extern "C" OEMCryptoResult OEMCrypto_GenerateRSASignature(
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
return pair.fcn->GenerateRSASignature(pair.session, message, message_length,
signature, signature_length,
padding_scheme);
if (pair.fcn->version == 8) {
return pair.fcn->GenerateRSASignature_V8(pair.session, message, message_length,
signature, signature_length);
} else {
return pair.fcn->GenerateRSASignature(pair.session, message, message_length,
signature, signature_length,
padding_scheme);
}
}
extern "C" OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
@@ -672,4 +743,96 @@ extern "C" OEMCryptoResult OEMCrypto_Generic_Verify(
algorithm, signature, signature_length);
}
extern "C"
OEMCryptoResult OEMCrypto_GetHDCPCapability(OEMCrypto_HDCP_Capability *current,
OEMCrypto_HDCP_Capability *maximum) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
const FunctionPointers* fcn = kAdapter->get(kLevelDefault);
if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if( fcn->version == 8 ) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return fcn->GetHDCPCapability(current, maximum);
}
extern "C" bool OEMCrypto_SupportsUsageTable() {
return OEMCrypto_SupportsUsageTable(kLevelDefault);
}
bool OEMCrypto_SupportsUsageTable(SecurityLevel level) {
if (!kAdapter) return false;
const FunctionPointers* fcn = kAdapter->get(level);
if (!fcn) return false;
if( fcn->version == 8 ) return false;
return fcn->SupportsUsageTable();
}
extern "C" OEMCryptoResult OEMCrypto_UpdateUsageTable() {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
const FunctionPointers* fcn1 = kAdapter->get(kLevelDefault);
const FunctionPointers* fcn3 = kAdapter->get(kLevel3);
OEMCryptoResult sts = OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (fcn3 && fcn3->version > 8) sts = fcn3->UpdateUsageTable();
if (fcn1 && fcn1 != fcn3 && fcn1->version > 8) sts = fcn1->UpdateUsageTable();
return sts;
}
extern "C" OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t *pst,
size_t pst_length) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
const FunctionPointers* fcn1 = kAdapter->get(kLevelDefault);
const FunctionPointers* fcn3 = kAdapter->get(kLevel3);
OEMCryptoResult sts = OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (fcn3 && fcn3->version > 8) {
sts = fcn3->DeactivateUsageEntry(pst, pst_length);
}
if (fcn1 && fcn1 != fcn3 && fcn1->version > 8) {
sts = fcn1->DeactivateUsageEntry(pst, pst_length);
}
return sts;
}
extern "C" OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session,
const uint8_t *pst,
size_t pst_length,
OEMCrypto_PST_Report *buffer,
size_t *buffer_length) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if( pair.fcn->version > 8 ) {
return pair.fcn->ReportUsage(pair.session, pst, pst_length,buffer,
buffer_length);
} else {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
}
extern "C" OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION session,
const uint8_t* pst,
size_t pst_length,
const uint8_t *message,
size_t message_length,
const uint8_t *signature,
size_t signature_length) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if( pair.fcn->version > 8 ) {
return pair.fcn->DeleteUsageEntry(session, pst, pst_length, message,
message_length, signature,
signature_length);
} else {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
}
extern "C" OEMCryptoResult OEMCrypto_DeleteUsageTable() {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
const FunctionPointers* fcn1 = kAdapter->get(kLevelDefault);
const FunctionPointers* fcn3 = kAdapter->get(kLevel3);
OEMCryptoResult sts = OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (fcn3 && fcn3->version > 8) sts = fcn3->DeleteUsageTable();
if (fcn1 && fcn1 != fcn3 && fcn1->version > 8) sts = fcn1->DeleteUsageTable();
return sts;
}
}; // namespace wvcdm

View File

@@ -43,6 +43,13 @@ namespace wvoec3 {
#define Level3_Generic_Decrypt _lcc25
#define Level3_Generic_Sign _lcc26
#define Level3_Generic_Verify _lcc27
#define Level3_GetHDCPCapability _lcc28
#define Level3_SupportsUsageTable _lcc29
#define Level3_UpdateUsageTable _lcc30
#define Level3_DeactivateUsageEntry _lcc31
#define Level3_ReportUsage _lcc32
#define Level3_DeleteUsageEntry _lcc33
#define Level3_DeleteUsageTable _lcc34
extern "C" {
@@ -159,7 +166,25 @@ OEMCryptoResult Level3_Generic_Verify(OEMCrypto_SESSION session,
OEMCrypto_Algorithm algorithm,
const uint8_t* signature,
size_t signature_length);
OEMCryptoResult Level3_GetHDCPCapability(OEMCrypto_HDCP_Capability *current,
OEMCrypto_HDCP_Capability *maximum);
bool Level3_SupportsUsageTable();
OEMCryptoResult Level3_UpdateUsageTable();
OEMCryptoResult Level3_DeactivateUsageEntry(const uint8_t *pst,
size_t pst_length);
OEMCryptoResult Level3_ReportUsage(OEMCrypto_SESSION session,
const uint8_t *pst,
size_t pst_length,
OEMCrypto_PST_Report *buffer,
size_t *buffer_length);
OEMCryptoResult Level3_DeleteUsageEntry(OEMCrypto_SESSION session,
const uint8_t* pst,
size_t pst_length,
const uint8_t *message,
size_t message_length,
const uint8_t *signature,
size_t signature_length);
OEMCryptoResult Level3_DeleteUsageTable();
};
}
#endif // LEVEL3_OEMCRYPTO_H_