Source release v3.0.0-0-g8d3792b-ce + third_party

Change-Id: I399e71ddfffcd436171d1c60283c63ab4658e0b1
This commit is contained in:
Joey Parrish
2015-06-19 15:13:34 -07:00
parent 58aba6b2ec
commit 0546ee6732
965 changed files with 426663 additions and 12897 deletions

View File

@@ -6,6 +6,7 @@
#include "crypto_session.h"
#include <arpa/inet.h> // needed for ntoh()
#include <string.h>
#include <iostream>
#include "crypto_key.h"
@@ -24,6 +25,7 @@ std::string EncodeUint32(unsigned int u) {
s.append(1, (u >> 0) & 0xFF);
return s;
}
const uint32_t kRsaSignatureLength = 256;
}
namespace wvcdm {
@@ -35,6 +37,7 @@ uint64_t CryptoSession::request_id_index_ = 0;
CryptoSession::CryptoSession()
: open_(false),
update_usage_table_after_close_session_(false),
is_destination_buffer_type_valid_(false),
requested_security_level_(kLevelDefault),
request_id_base_(0) {
@@ -64,7 +67,11 @@ void CryptoSession::Init() {
void CryptoSession::Terminate() {
LOGV("CryptoSession::Terminate");
AutoLock auto_lock(crypto_lock_);
session_count_ -= 1;
if (session_count_ > 0) {
session_count_ -= 1;
} else {
LOGE("CryptoSession::Terminate error, session count: %d", session_count_);
}
if (session_count_ > 0 || !initialized_) return;
OEMCryptoResult sts = OEMCrypto_Terminate();
if (OEMCrypto_SUCCESS != sts) {
@@ -168,8 +175,6 @@ bool CryptoSession::GetApiVersion(uint32_t* version) {
if (!initialized_) {
return false;
}
LOGV("CryptoSession::GetApiVersion: Lock");
*version = OEMCrypto_APIVersion(requested_security_level_);
return true;
}
@@ -242,9 +247,15 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
LOGV("OpenSession: id= %ld", (uint32_t)oec_session_id_);
open_ = true;
} else if (OEMCrypto_ERROR_TOO_MANY_SESSIONS == sts) {
LOGE("OEMCrypto_Open failed: %d, open sessions: %ld, initialized: %d", sts,
session_count_, (int)initialized_);
return INSUFFICIENT_CRYPTO_RESOURCES;
}
if (!open_) return UNKNOWN_ERROR;
if (!open_) {
LOGE("OEMCrypto_Open failed: %d, open sessions: %ld, initialized: %d", sts,
session_count_, (int)initialized_);
return UNKNOWN_ERROR;
}
OEMCrypto_GetRandom(reinterpret_cast<uint8_t*>(&request_id_base_),
sizeof(request_id_base_));
@@ -259,6 +270,11 @@ void CryptoSession::Close() {
if (!open_) return;
if (OEMCrypto_SUCCESS == OEMCrypto_CloseSession(oec_session_id_)) {
open_ = false;
if (update_usage_table_after_close_session_) {
OEMCryptoResult sts = OEMCrypto_UpdateUsageTable();
if (sts != OEMCrypto_SUCCESS)
LOGW("CryptoSession::Close: OEMCrypto_UpdateUsageTable error=%ld", sts);
}
}
}
@@ -410,13 +426,21 @@ CdmResponseType CryptoSession::LoadKeys(
provider_session_token.length());
if (OEMCrypto_SUCCESS == sts) {
if (!provider_session_token.empty()) {
update_usage_table_after_close_session_ = true;
sts = OEMCrypto_UpdateUsageTable();
if (sts != OEMCrypto_SUCCESS) {
LOGW("CryptoSession::LoadKeys: OEMCrypto_UpdateUsageTable error=%ld",
sts);
}
}
return KEY_ADDED;
} else if (OEMCrypto_ERROR_TOO_MANY_KEYS == sts) {
LOGE("LoadKeys: OEMCrypto_LoadKeys error=%d", sts);
LOGE("CryptoSession::LoadKeys: OEMCrypto_LoadKeys error=%d", sts);
return INSUFFICIENT_CRYPTO_RESOURCES;
} else {
LOGE("LoadKeys: OEMCrypto_LoadKeys error=%d", sts);
return KEY_ERROR;
LOGE("CryptoSession::LoadKeys: OEMCrypto_LoadKeys error=%d", sts);
return LOAD_KEY_ERROR;
}
}
@@ -430,7 +454,7 @@ bool CryptoSession::LoadCertificatePrivateKey(std::string& wrapped_key) {
wrapped_key.size());
if (OEMCrypto_SUCCESS != sts) {
LOGD("LoadCertificatePrivateKey: OEMCrypto_LoadDeviceRSAKey error=%d", sts);
LOGE("LoadCertificatePrivateKey: OEMCrypto_LoadDeviceRSAKey error=%d", sts);
return false;
}
@@ -500,7 +524,7 @@ bool CryptoSession::GenerateDerivedKeys(const std::string& message) {
enc_deriv_message.size());
if (OEMCrypto_SUCCESS != sts) {
LOGD("GenerateDerivedKeys: OEMCrypto_GenerateDerivedKeys error=%d", sts);
LOGE("GenerateDerivedKeys: OEMCrypto_GenerateDerivedKeys error=%d", sts);
return false;
}
@@ -524,7 +548,7 @@ bool CryptoSession::GenerateDerivedKeys(const std::string& message,
enc_deriv_message.size());
if (OEMCrypto_SUCCESS != sts) {
LOGD("GenerateDerivedKeys: OEMCrypto_DeriveKeysFromSessionKey err=%d", sts);
LOGE("GenerateDerivedKeys: OEMCrypto_DeriveKeysFromSessionKey err=%d", sts);
return false;
}
@@ -545,7 +569,7 @@ bool CryptoSession::GenerateSignature(const std::string& message,
if (OEMCrypto_SUCCESS != sts) {
if (OEMCrypto_ERROR_SHORT_BUFFER != sts) {
LOGD("GenerateSignature: OEMCrypto_GenerateSignature err=%d", sts);
LOGE("GenerateSignature: OEMCrypto_GenerateSignature err=%d", sts);
return false;
}
@@ -558,7 +582,7 @@ bool CryptoSession::GenerateSignature(const std::string& message,
&length);
if (OEMCrypto_SUCCESS != sts) {
LOGD("GenerateSignature: OEMCrypto_GenerateSignature err=%d", sts);
LOGE("GenerateSignature: OEMCrypto_GenerateSignature err=%d", sts);
return false;
}
}
@@ -574,6 +598,7 @@ bool CryptoSession::GenerateRsaSignature(const std::string& message,
LOGV("GenerateRsaSignature: id=%ld", (uint32_t)oec_session_id_);
if (!signature) return false;
signature->resize(kRsaSignatureLength);
size_t length = signature->size();
OEMCryptoResult sts = OEMCrypto_GenerateRSASignature(
oec_session_id_, reinterpret_cast<const uint8_t*>(message.data()),
@@ -583,7 +608,7 @@ bool CryptoSession::GenerateRsaSignature(const std::string& message,
if (OEMCrypto_SUCCESS != sts) {
if (OEMCrypto_ERROR_SHORT_BUFFER != sts) {
LOGD("GenerateRsaSignature: OEMCrypto_GenerateRSASignature err=%d", sts);
LOGE("GenerateRsaSignature: OEMCrypto_GenerateRSASignature err=%d", sts);
return false;
}
@@ -596,7 +621,7 @@ bool CryptoSession::GenerateRsaSignature(const std::string& message,
&length, kSign_RSASSA_PSS);
if (OEMCrypto_SUCCESS != sts) {
LOGD("GenerateRsaSignature: OEMCrypto_GenerateRSASignature err=%d", sts);
LOGE("GenerateRsaSignature: OEMCrypto_GenerateRSASignature err=%d", sts);
return false;
}
}
@@ -612,18 +637,6 @@ CdmResponseType CryptoSession::Decrypt(const CdmDecryptionParameters& params) {
if (!SetDestinationBufferType()) return UNKNOWN_ERROR;
}
AutoLock auto_lock(crypto_lock_);
// Check if key needs to be selected
if (params.is_encrypted) {
if (key_id_ != *params.key_id) {
if (SelectKey(*params.key_id)) {
key_id_ = *params.key_id;
} else {
return NEED_KEY;
}
}
}
OEMCrypto_DestBufferDesc buffer_descriptor;
buffer_descriptor.type =
params.is_secure ? destination_buffer_type_ : OEMCrypto_BufferType_Clear;
@@ -647,10 +660,29 @@ CdmResponseType CryptoSession::Decrypt(const CdmDecryptionParameters& params) {
break;
}
OEMCryptoResult sts = OEMCrypto_DecryptCTR(
oec_session_id_, params.encrypt_buffer, params.encrypt_length,
params.is_encrypted, &(*params.iv).front(), params.block_offset,
&buffer_descriptor, params.subsample_flags);
OEMCryptoResult sts = OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (!params.is_encrypted) {
sts = OEMCrypto_CopyBuffer(requested_security_level_,
params.encrypt_buffer, params.encrypt_length,
&buffer_descriptor, params.subsample_flags);
}
if (params.is_encrypted || sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
AutoLock auto_lock(crypto_lock_);
// Check if key needs to be selected
if (params.is_encrypted) {
if (key_id_ != *params.key_id) {
if (SelectKey(*params.key_id)) {
key_id_ = *params.key_id;
} else {
return NEED_KEY;
}
}
}
sts = OEMCrypto_DecryptCTR(
oec_session_id_, params.encrypt_buffer, params.encrypt_length,
params.is_encrypted, &(*params.iv).front(), params.block_offset,
&buffer_descriptor, params.subsample_flags);
}
switch (sts) {
case OEMCrypto_SUCCESS:
@@ -668,8 +700,7 @@ bool CryptoSession::UsageInformationSupport(bool* has_support) {
LOGV("UsageInformationSupport: id=%ld", (uint32_t)oec_session_id_);
if (!initialized_) return false;
*has_support = OEMCrypto_SupportsUsageTable(
kSecurityLevelL3 == GetSecurityLevel() ? kLevel3 : kLevelDefault);
*has_support = OEMCrypto_SupportsUsageTable(requested_security_level_);
return true;
}
@@ -686,14 +717,9 @@ CdmResponseType CryptoSession::UpdateUsageInformation() {
return NO_ERROR;
}
CdmResponseType CryptoSession::GenerateUsageReport(
const std::string& provider_session_token, std::string* usage_report) {
LOGV("GenerateUsageReport: id=%ld", (uint32_t)oec_session_id_);
if (NULL == usage_report) {
LOGE("usage_report parameter is null");
return UNKNOWN_ERROR;
}
CdmResponseType CryptoSession::DeactivateUsageInformation(
const std::string& provider_session_token) {
LOGV("DeactivateUsageInformation: id=%ld", (uint32_t)oec_session_id_);
AutoLock auto_lock(crypto_lock_);
uint8_t* pst = reinterpret_cast<uint8_t*>(
@@ -702,20 +728,44 @@ CdmResponseType CryptoSession::GenerateUsageReport(
OEMCryptoResult status =
OEMCrypto_DeactivateUsageEntry(pst, provider_session_token.length());
if (OEMCrypto_SUCCESS != status) {
LOGE("CryptoSession::GenerateUsageReport: Deactivate Usage Entry error=%ld",
status);
switch (status) {
case OEMCrypto_SUCCESS:
return NO_ERROR;
case OEMCrypto_ERROR_INVALID_CONTEXT:
LOGE("CryptoSession::DeactivateUsageInformation: invalid context error");
return KEY_CANCELED;
default:
LOGE("CryptoSession::DeactivateUsageInformation: error=%ld", status);
return UNKNOWN_ERROR;
}
}
CdmResponseType CryptoSession::GenerateUsageReport(
const std::string& provider_session_token, std::string* usage_report,
UsageDurationStatus* usage_duration_status, int64_t* seconds_since_started,
int64_t* seconds_since_last_played) {
LOGV("GenerateUsageReport: id=%ld", (uint32_t)oec_session_id_);
if (NULL == usage_report) {
LOGE("CryptoSession::GenerateUsageReport: usage_report parameter is null");
return UNKNOWN_ERROR;
}
size_t usage_length = 0;
status = OEMCrypto_ReportUsage(oec_session_id_, pst,
provider_session_token.length(), NULL,
&usage_length);
AutoLock auto_lock(crypto_lock_);
uint8_t* pst = reinterpret_cast<uint8_t*>(
const_cast<char*>(provider_session_token.data()));
if (OEMCrypto_ERROR_SHORT_BUFFER != status) {
LOGE("CryptoSession::GenerateUsageReport: Report Usage error=%ld", status);
return UNKNOWN_ERROR;
size_t usage_length = 0;
OEMCryptoResult status = OEMCrypto_ReportUsage(
oec_session_id_, pst, provider_session_token.length(), NULL,
&usage_length);
if (OEMCrypto_SUCCESS != status) {
if (OEMCrypto_ERROR_SHORT_BUFFER != status) {
LOGE("CryptoSession::GenerateUsageReport: Report Usage error=%ld",
status);
return UNKNOWN_ERROR;
}
}
usage_report->resize(usage_length);
@@ -730,10 +780,49 @@ CdmResponseType CryptoSession::GenerateUsageReport(
return UNKNOWN_ERROR;
}
if (usage_length < usage_report->length()) {
if (usage_length != usage_report->length()) {
usage_report->resize(usage_length);
}
OEMCrypto_PST_Report pst_report;
*usage_duration_status = kUsageDurationsInvalid;
if (usage_length < sizeof(pst_report)) {
LOGE("CryptoSession::GenerateUsageReport: usage report too small=%ld",
usage_length);
return NO_ERROR; // usage report available but no duration information
}
memcpy(&pst_report, usage_report->data(), sizeof(pst_report));
if (kUnused == pst_report.status) {
*usage_duration_status = kUsageDurationPlaybackNotBegun;
return NO_ERROR;
}
LOGV("OEMCrypto_PST_Report.status: %d\n", pst_report.status);
LOGV("OEMCrypto_PST_Report.clock_security_level: %d\n",
pst_report.clock_security_level);
LOGV("OEMCrypto_PST_Report.pst_length: %d\n", pst_report.pst_length);
LOGV("OEMCrypto_PST_Report.padding: %d\n", pst_report.padding);
LOGV("OEMCrypto_PST_Report.seconds_since_license_received: %lld\n",
ntohll64(pst_report.seconds_since_license_received));
LOGV("OEMCrypto_PST_Report.seconds_since_first_decrypt: %lld\n",
ntohll64(pst_report.seconds_since_first_decrypt));
LOGV("OEMCrypto_PST_Report.seconds_since_last_decrypt: %lld\n",
ntohll64(pst_report.seconds_since_last_decrypt));
LOGV("OEMCrypto_PST_Report: %s\n", b2a_hex(*usage_report).c_str());
// When usage report state is inactive, we have to deduce whether the
// license was ever used.
if (kInactive == pst_report.status &&
(0 > ntohll64(pst_report.seconds_since_first_decrypt) ||
ntohll64(pst_report.seconds_since_license_received) <
ntohll64(pst_report.seconds_since_first_decrypt))) {
*usage_duration_status = kUsageDurationPlaybackNotBegun;
return NO_ERROR;
}
*usage_duration_status = kUsageDurationsValid;
*seconds_since_started = ntohll64(pst_report.seconds_since_first_decrypt);
*seconds_since_last_played = ntohll64(pst_report.seconds_since_last_decrypt);
return NO_ERROR;
}
@@ -755,10 +844,81 @@ CdmResponseType CryptoSession::ReleaseUsageInformation(
status);
return UNKNOWN_ERROR;
}
status = OEMCrypto_UpdateUsageTable();
if (status != OEMCrypto_SUCCESS) {
LOGW("CryptoSession::ReleaseUsageInformation: update table error=%ld",
status);
}
return NO_ERROR;
}
CdmResponseType CryptoSession::DeleteUsageInformation(
const std::string& provider_session_token) {
CdmResponseType response = NO_ERROR;
LOGV("CryptoSession::DeleteUsageInformation");
OEMCryptoResult status = OEMCrypto_ForceDeleteUsageEntry(
reinterpret_cast<const uint8_t*>(provider_session_token.c_str()),
provider_session_token.length());
if (OEMCrypto_SUCCESS != status) {
LOGE("CryptoSession::DeleteUsageInformation: Delete Usage Table error =%ld",
status);
response = UNKNOWN_ERROR;
}
status = OEMCrypto_UpdateUsageTable();
if (status != OEMCrypto_SUCCESS) {
LOGE("CryptoSession::DeleteUsageInformation: update table error=%ld",
status);
response = UNKNOWN_ERROR;
}
return response;
}
CdmResponseType CryptoSession::DeleteMultipleUsageInformation(
const std::vector<std::string>& provider_session_tokens) {
LOGV("CryptoSession::DeleteMultipleUsageInformation");
CdmResponseType response = NO_ERROR;
for (size_t i=0; i < provider_session_tokens.size(); ++i) {
OEMCryptoResult status = OEMCrypto_ForceDeleteUsageEntry(
reinterpret_cast<const uint8_t*>(provider_session_tokens[i].c_str()),
provider_session_tokens[i].length());
if (OEMCrypto_SUCCESS != status) {
LOGW("CryptoSession::DeleteMultipleUsageInformation: "
"Delete Usage Table error =%ld", status);
response = UNKNOWN_ERROR;
}
}
OEMCryptoResult status = OEMCrypto_UpdateUsageTable();
if (status != OEMCrypto_SUCCESS) {
LOGE("CryptoSession::DeleteMultipleUsageInformation: update table error=%ld",
status);
response = UNKNOWN_ERROR;
}
return response;
}
CdmResponseType CryptoSession::DeleteAllUsageReports() {
LOGV("DeleteAllUsageReports");
OEMCryptoResult status = OEMCrypto_DeleteUsageTable();
if (OEMCrypto_SUCCESS != status) {
LOGE("CryptoSession::DeleteAllUsageReports: Delete Usage Table error =%ld",
status);
}
status = OEMCrypto_UpdateUsageTable();
if (status != OEMCrypto_SUCCESS) {
LOGE("CryptoSession::DeletaAllUsageReports: update table error=%ld",
status);
return UNKNOWN_ERROR;
}
return NO_ERROR;
}
bool CryptoSession::IsAntiRollbackHwPresent() {
return OEMCrypto_IsAntiRollbackHwPresent(requested_security_level_);
}
bool CryptoSession::GenerateNonce(uint32_t* nonce) {
if (!nonce) {
LOGE("input parameter is null");
@@ -796,7 +956,7 @@ bool CryptoSession::RewrapDeviceRSAKey(const std::string& message,
const std::string& enc_rsa_key,
const std::string& rsa_key_iv,
std::string* wrapped_rsa_key) {
LOGD("CryptoSession::RewrapDeviceRSAKey, session id=%ld",
LOGV("CryptoSession::RewrapDeviceRSAKey, session id=%ld",
static_cast<uint32_t>(oec_session_id_));
const uint8_t* signed_msg = reinterpret_cast<const uint8_t*>(message.data());
@@ -841,20 +1001,20 @@ bool CryptoSession::RewrapDeviceRSAKey(const std::string& message,
return true;
}
bool CryptoSession::GetHdcpCapabilities(OemCryptoHdcpVersion* current_version,
OemCryptoHdcpVersion* max_version) {
bool CryptoSession::GetHdcpCapabilities(HdcpCapability* current,
HdcpCapability* max) {
LOGV("GetHdcpCapabilities: id=%ld", (uint32_t)oec_session_id_);
if (!initialized_) return UNKNOWN_ERROR;
OEMCrypto_HDCP_Capability current, max;
OEMCryptoResult status = OEMCrypto_GetHDCPCapability(&current, &max);
if (!initialized_) return false;
if (current == NULL || max == NULL) {
LOGE("CryptoSession::GetHdcpCapabilities: |current|, |max| cannot be NULL");
return false;
}
OEMCryptoResult status = OEMCrypto_GetHDCPCapability(
requested_security_level_, current, max);
if (OEMCrypto_SUCCESS != status) {
LOGW("OEMCrypto_GetHDCPCapability fails with %d", status);
return false;
}
*current_version = static_cast<OemCryptoHdcpVersion>(current);
*max_version = static_cast<OemCryptoHdcpVersion>(max);
return true;
}
@@ -873,4 +1033,42 @@ bool CryptoSession::GetRandom(size_t data_length, uint8_t* random_data) {
return true;
}
}; // namespace wvcdm
bool CryptoSession::GetNumberOfOpenSessions(size_t* count) {
LOGV("GetNumberOfOpenSessions");
if (!initialized_) return false;
if (count == NULL) {
LOGE("CryptoSession::GetNumberOfOpenSessions: |count| cannot be NULL");
return false;
}
size_t sessions_count;
OEMCryptoResult status = OEMCrypto_GetNumberOfOpenSessions(
requested_security_level_, &sessions_count);
if (OEMCrypto_SUCCESS != status) {
LOGW("OEMCrypto_GetNumberOfOpenSessions fails with %d", status);
return false;
}
*count = sessions_count;
return true;
}
bool CryptoSession::GetMaxNumberOfSessions(size_t* max) {
LOGV("GetMaxNumberOfSessions");
if (!initialized_) return false;
if (max == NULL) {
LOGE("CryptoSession::GetMaxNumberOfSessions: |max| cannot be NULL");
return false;
}
size_t max_sessions;
OEMCryptoResult status = OEMCrypto_GetMaxNumberOfSessions(
requested_security_level_, &max_sessions);
if (OEMCrypto_SUCCESS != status) {
LOGW("OEMCrypto_GetMaxNumberOfSessions fails with %d", status);
return false;
}
*max = max_sessions;
return true;
}
} // namespace wvcdm