Support CAST V2 authentication - OEMCrypto Interface - DO NOT MERGE

Squashed commit of these CLs from the widevine cdm repo:

Allow Version 8 OEMCrypto to be linked with CDM (KLP Modular Branch)
https://widevine-internal-review.googlesource.com/#/c/9434/

Allow OEMCrypto v8 or v9 (KLP Modular Branch)
https://widevine-internal-review.googlesource.com/#/c/9172/

Add alternate RSA signing (KLP Modular Branch)
https://widevine-internal-review.googlesource.com/#/c/9171/

bug: 12702350
Change-Id: Ifd0c88c566bb10efe2411af49bc83265ed56cb23
This commit is contained in:
Fred Gylys-Colwell
2014-03-24 13:46:38 -07:00
parent f1e87b1b04
commit a59b935928
14 changed files with 1930 additions and 322 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,
@@ -90,7 +95,12 @@ typedef OEMCryptoResult (*L1_GenerateRSASignature_t)(OEMCrypto_SESSION session,
size_t message_length,
uint8_t* signature,
size_t* signature_length,
RSA_Padding_Scheme algorithm);
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 {
@@ -212,7 +252,6 @@ class Adapter {
LOOKUP(GenerateDerivedKeys, OEMCrypto_GenerateDerivedKeys);
LOOKUP(GenerateNonce, OEMCrypto_GenerateNonce);
LOOKUP(GenerateSignature, OEMCrypto_GenerateSignature);
LOOKUP(LoadKeys, OEMCrypto_LoadKeys);
LOOKUP(RefreshKeys, OEMCrypto_RefreshKeys);
LOOKUP(SelectKey, OEMCrypto_SelectKey);
LOOKUP(DecryptCTR, OEMCrypto_DecryptCTR);
@@ -224,7 +263,6 @@ class Adapter {
LOOKUP(WrapKeybox, OEMCrypto_WrapKeybox);
LOOKUP(RewrapDeviceRSAKey, OEMCrypto_RewrapDeviceRSAKey);
LOOKUP(LoadDeviceRSAKey, OEMCrypto_LoadDeviceRSAKey);
LOOKUP(GenerateRSASignature, OEMCrypto_GenerateRSASignature);
LOOKUP(DeriveKeysFromSessionKey, OEMCrypto_DeriveKeysFromSessionKey);
LOOKUP(APIVersion, OEMCrypto_APIVersion);
LOOKUP(SecurityLevel, OEMCrypto_SecurityLevel);
@@ -240,13 +278,27 @@ class Adapter {
LOGW("Could not initialize L1. Falling Back to L3.");
return false;
}
uint32_t level1_version = level1_.APIVersion();
level1_.version = level1_.APIVersion();
uint32_t minimum_version = 8; // TODO(fredgc): allow version 8 and 9?
if (level1_version < minimum_version) {
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_V8);
LOOKUP(GenerateRSASignature_V8, OEMCrypto_GenerateRSASignature_V8);
} else {
LOOKUP(LoadKeys, OEMCrypto_LoadKeys);
LOOKUP(GenerateRSASignature, OEMCrypto_GenerateRSASignature);
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() {
@@ -318,7 +378,7 @@ class Adapter {
}
LevelSession get(OEMCrypto_SESSION session) {
AutoLock auto_lock(lookup_lock_);
AutoLock auto_lock(session_map_lock_);
map_iterator pair = session_map_.find(session);
if (pair == session_map_.end()) {
return LevelSession();
@@ -327,7 +387,6 @@ class Adapter {
}
OEMCryptoResult OpenSession(OEMCrypto_SESSION* session, SecurityLevel level) {
AutoLock auto_lock(lookup_lock_);
LevelSession new_session;
OEMCryptoResult result;
if (level == kLevelDefault && level1_valid_) {
@@ -340,6 +399,7 @@ class Adapter {
*session = new_session.session + kLevel3Offset;
}
if (result == OEMCrypto_SUCCESS) {
AutoLock auto_lock(session_map_lock_);
// Make sure session is not already in my list of sessions.
while (session_map_.find(*session) != session_map_.end()) {
(*session)++;
@@ -350,7 +410,7 @@ class Adapter {
}
OEMCryptoResult CloseSession(OEMCrypto_SESSION session) {
AutoLock auto_lock(lookup_lock_);
AutoLock auto_lock(session_map_lock_);
map_iterator pair = session_map_.find(session);
if (pair == session_map_.end()) {
return OEMCrypto_ERROR_INVALID_SESSION;
@@ -367,7 +427,7 @@ class Adapter {
struct FunctionPointers level1_;
struct FunctionPointers level3_;
std::map<OEMCrypto_SESSION, LevelSession> session_map_;
Lock lookup_lock_;
Lock session_map_lock_;
// This is just for debugging the map between session ids.
// If we add this to the level 3 session id, then the external session
// id will match the internal session id in the last two digits.
@@ -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(
@@ -583,12 +649,18 @@ extern "C" OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(
extern "C" OEMCryptoResult OEMCrypto_GenerateRSASignature(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
uint8_t* signature, size_t* signature_length, RSA_Padding_Scheme algorithm) {
uint8_t* signature, size_t* signature_length, RSA_Padding_Scheme padding_scheme) {
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, algorithm);
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(
@@ -671,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

@@ -0,0 +1,127 @@
/*******************************************************************************
*
* Copyright 2013 Google Inc. All Rights Reserved.
*
* Wrapper of OEMCrypto APIs for platforms that support Level 1 only.
* This should be used when liboemcrypto.so is linked with the CDM code at
* compile time.
* An implementation should compile either oemcrypto_adapter_dynamic.cpp or
* oemcrypto_adapter_static.cpp, but not both.
* This version contains shim code to allow an older, version 8 API, oemcrypto,
* to be linked with CDM.
*
******************************************************************************/
#include "OEMCryptoCENC.h"
#include "oemcrypto_adapter.h"
extern "C"
OEMCryptoResult OEMCrypto_LoadKeys_V8(OEMCrypto_SESSION session,
const uint8_t* message,
size_t message_length,
const uint8_t* signature,
size_t signature_length,
const uint8_t* enc_mac_keys_iv,
const uint8_t* enc_mac_keys,
size_t num_keys,
const OEMCrypto_KeyObject* key_array);
extern "C"
OEMCryptoResult OEMCrypto_GenerateRSASignature_V8(OEMCrypto_SESSION session,
const uint8_t* message,
size_t message_length,
uint8_t* signature,
size_t *signature_length);
namespace wvcdm {
OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session,
SecurityLevel level) {
return ::OEMCrypto_OpenSession(session);
}
OEMCryptoResult OEMCrypto_IsKeyboxValid(SecurityLevel level) {
return ::OEMCrypto_IsKeyboxValid();
}
OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID, size_t* idLength,
SecurityLevel level) {
return ::OEMCrypto_GetDeviceID(deviceID, idLength);
}
OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData, size_t* keyDataLength,
SecurityLevel level) {
return ::OEMCrypto_GetKeyData(keyData, keyDataLength);
}
OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox,
size_t keyBoxLength,
SecurityLevel level) {
return ::OEMCrypto_InstallKeybox(keybox, keyBoxLength);
}
uint32_t OEMCrypto_APIVersion(SecurityLevel level) {
return ::OEMCrypto_APIVersion();
}
const char* OEMCrypto_SecurityLevel(SecurityLevel level) {
return ::OEMCrypto_SecurityLevel();
}
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) {
return LoadKeys_V8(pair.session, message, message_length, signature,
signature_length, enc_mac_key_iv, enc_mac_key,
num_keys, key_array);
}
extern "C" OEMCryptoResult OEMCrypto_GenerateRSASignature(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
uint8_t* signature, size_t* signature_length, RSA_Padding_Scheme padding_scheme) {
return GenerateRSASignature_V8(pair.session, message, message_length,
signature, signature_length);
}
extern "C"
OEMCryptoResult OEMCrypto_GetHDCPCapability(OEMCrypto_HDCP_Capability *current,
OEMCrypto_HDCP_Capability *maximum) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
extern "C" bool OEMCrypto_SupportsUsageTable() {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
extern "C" OEMCryptoResult OEMCrypto_UpdateUsageTable() {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
extern "C" OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t *pst,
size_t pst_length) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
extern "C" OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session,
const uint8_t *pst,
size_t pst_length,
OEMCrypto_PST_Report *buffer,
size_t *buffer_length) {
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) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
}; // namespace wvcdm