Support provisioning 3.0

[ Merge of http://go/wvgerrit/29004 ]

Enable support for provisioning with OEM certificates as root of
trust.

b/62972441

Test: WV unit/intgration test, cdm_feature_test and GTSMediaTestCases

Change-Id: I30576fc0bb68a873eeaaca03f6b9c89fa6a14327
This commit is contained in:
Rahul Frias
2017-07-17 02:40:50 -07:00
parent a81caa5bf1
commit e61259e075
13 changed files with 506 additions and 61 deletions

View File

@@ -162,7 +162,15 @@ bool CryptoSession::GetTokenFromKeybox(std::string* token) {
}
bool CryptoSession::GetTokenFromOemCert(std::string* token) {
if (token == NULL) {
LOGE("CryptoSession::GetTokenFromOemCert: token not provided ");
return false;
}
OEMCryptoResult status;
if (!oem_token_.empty()) {
token->assign(oem_token_);
return true;
}
std::string temp_buffer(CERTIFICATE_DATA_SIZE, '\0');
// lock is held by caller
bool retrying = false;
@@ -171,7 +179,9 @@ bool CryptoSession::GetTokenFromOemCert(std::string* token) {
uint8_t* buf = reinterpret_cast<uint8_t*>(&temp_buffer[0]);
status = OEMCrypto_GetOEMPublicCertificate(oec_session_id_, buf, &buf_size);
if (OEMCrypto_SUCCESS == status) {
token->swap(temp_buffer);
temp_buffer.resize(buf_size);
oem_token_.assign(temp_buffer);
token->assign(temp_buffer);
return true;
}
if (OEMCrypto_ERROR_SHORT_BUFFER && !retrying) {
@@ -568,8 +578,8 @@ bool CryptoSession::PrepareRequest(const std::string& message,
return false;
}
// TODO(gmorgan): rework this for OEM certs.
if (!Properties::use_certificates_as_identification() || is_provisioning) {
if (!Properties::use_certificates_as_identification() ||
(is_provisioning && (pre_provision_token_type_ == kClientTokenKeybox))) {
if (!GenerateDerivedKeys(message)) return false;
if (!GenerateSignature(message, signature)) return false;
@@ -739,8 +749,15 @@ bool CryptoSession::LoadCertificatePrivateKey(std::string& wrapped_key) {
LOGV("CryptoSession::LoadCertificatePrivateKey: Lock");
AutoLock auto_lock(crypto_lock_);
// Call OEMCrypto_GetOEMPublicCertificate before OEMCrypto_LoadDeviceRSAKey
// so it caches the OEMCrypto Public Key and then throw away result
std::string temp_buffer(CERTIFICATE_DATA_SIZE, '\0');
size_t buf_size = temp_buffer.size();
uint8_t* buf = reinterpret_cast<uint8_t*>(&temp_buffer[0]);
OEMCryptoResult sts =
OEMCrypto_GetOEMPublicCertificate(oec_session_id_, buf, &buf_size);
LOGV("LoadDeviceRSAKey: id=%ld", (uint32_t)oec_session_id_);
OEMCryptoResult sts;
M_TIME(
sts = OEMCrypto_LoadDeviceRSAKey(
oec_session_id_,
@@ -1458,6 +1475,34 @@ bool CryptoSession::SetDestinationBufferType() {
return true;
}
bool CryptoSession::RewrapCertificate(const std::string& signed_message,
const std::string& signature,
const std::string& nonce,
const std::string& private_key,
const std::string& iv,
const std::string& wrapping_key,
std::string* wrapped_private_key) {
LOGV("CryptoSession::RewrapCertificate, session id=%ld",
static_cast<uint32_t>(oec_session_id_));
if (pre_provision_token_type_ == kClientTokenKeybox) {
return RewrapDeviceRSAKey(signed_message, signature, nonce, private_key,
iv, wrapped_private_key);
} else if (pre_provision_token_type_ == kClientTokenOemCert) {
return RewrapDeviceRSAKey30(signed_message, nonce, private_key, iv,
wrapping_key, wrapped_private_key);
} else {
LOGE("CryptoSession::RewrapCertificate, Bad pre-provision type=%d: "
"session id=%ld", pre_provision_token_type_,
static_cast<uint32_t>(oec_session_id_));
return false;
}
}
bool CryptoSession::RewrapDeviceRSAKey(const std::string& message,
const std::string& signature,
const std::string& nonce,
@@ -1531,6 +1576,57 @@ bool CryptoSession::RewrapDeviceRSAKey(const std::string& message,
return true;
}
bool CryptoSession::RewrapDeviceRSAKey30(const std::string& message,
const std::string& nonce,
const std::string& private_key,
const std::string& iv,
const std::string& wrapping_key,
std::string* wrapped_private_key) {
LOGV("CryptoSession::RewrapDeviceRSAKey30, session id=%ld",
static_cast<uint32_t>(oec_session_id_));
const uint8_t* signed_msg = reinterpret_cast<const uint8_t*>(message.data());
const uint8_t* msg_private_key = NULL;
const uint8_t* msg_iv = NULL;
const uint32_t* msg_nonce = NULL;
const uint8_t* msg_wrapping_key = NULL;
if (private_key.size() >= MAC_KEY_SIZE && iv.size() >= KEY_IV_SIZE) {
msg_private_key = signed_msg + GetOffset(message, private_key);
msg_iv = signed_msg + GetOffset(message, iv);
msg_nonce = reinterpret_cast<const uint32_t*>(signed_msg +
GetOffset(message, nonce));
msg_wrapping_key = signed_msg + GetOffset(message, wrapping_key);
}
// Gets wrapped_rsa_key_length by passing NULL as uint8_t* wrapped_rsa_key
// and 0 as wrapped_rsa_key_length.
size_t wrapped_private_key_length = 0;
OEMCryptoResult status = OEMCrypto_RewrapDeviceRSAKey30(
oec_session_id_, msg_nonce, msg_wrapping_key, wrapping_key.size(),
msg_private_key, private_key.size(), msg_iv, NULL,
&wrapped_private_key_length);
if (status != OEMCrypto_ERROR_SHORT_BUFFER) {
LOGE("OEMCrypto_RewrapDeviceRSAKey30 failed getting wrapped key length");
return false;
}
wrapped_private_key->resize(wrapped_private_key_length);
status = OEMCrypto_RewrapDeviceRSAKey30(
oec_session_id_, msg_nonce, msg_wrapping_key, wrapping_key.size(),
msg_private_key, private_key.size(), msg_iv,
reinterpret_cast<uint8_t*>(&(*wrapped_private_key)[0]),
&wrapped_private_key_length);
wrapped_private_key->resize(wrapped_private_key_length);
if (OEMCrypto_SUCCESS != status) {
LOGE("OEMCrypto_RewrapDeviceRSAKey fails with %d", status);
return false;
}
return true;
}
bool CryptoSession::GetHdcpCapabilities(HdcpCapability* current,
HdcpCapability* max) {
LOGV("GetHdcpCapabilities: id=%ld", (uint32_t)oec_session_id_);