diff --git a/libwvdrmengine/cdm/core/include/crypto_session.h b/libwvdrmengine/cdm/core/include/crypto_session.h index 446dd8b5..58c2c792 100644 --- a/libwvdrmengine/cdm/core/include/crypto_session.h +++ b/libwvdrmengine/cdm/core/include/crypto_session.h @@ -91,6 +91,13 @@ class CryptoSession { virtual CdmResponseType GetProvisioningToken(std::string* token, std::string* additional_token); + virtual CdmResponseType GetProvisioning40TokenType( + RequestedSecurityLevel requested_security_level, + OEMCrypto_BCCType* bcc_type); + // Must be called after session is open. + virtual CdmResponseType GetProvisioning40TokenType( + OEMCrypto_BCCType* bcc_type); + virtual CdmClientTokenType GetPreProvisionTokenType() { return pre_provision_token_type_; } @@ -477,12 +484,12 @@ class CryptoSession { // otherwise, such as making two calls into OEMCrypto immediately after each // other. template - static auto WithStaticFieldWriteLock(const char* tag, Func body) - -> decltype(body()); + static auto WithStaticFieldWriteLock(const char* tag, + Func body) -> decltype(body()); template - static auto WithStaticFieldReadLock(const char* tag, Func body) - -> decltype(body()); + static auto WithStaticFieldReadLock(const char* tag, + Func body) -> decltype(body()); template static auto WithOecWriteLock(const char* tag, Func body) -> decltype(body()); diff --git a/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h b/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h index 79af2264..a38aa6f7 100644 --- a/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h +++ b/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h @@ -94,7 +94,8 @@ OEMCryptoResult OEMCrypto_Generic_Verify( size_t key_handle_length, const OEMCrypto_SharedMemory* buffer, size_t buffer_length, OEMCrypto_Algorithm algorithm, const OEMCrypto_SharedMemory* signature, size_t signature_length); - +OEMCryptoResult OEMCrypto_GetBCCType(RequestedSecurityLevel level, + OEMCrypto_BCCType* bcc_type); } // namespace wvcdm #endif // WVCDM_CORE_OEMCRYPTO_ADAPTER_H_ diff --git a/libwvdrmengine/cdm/core/src/client_identification.cpp b/libwvdrmengine/cdm/core/src/client_identification.cpp index 4a12df50..212d5115 100644 --- a/libwvdrmengine/cdm/core/src/client_identification.cpp +++ b/libwvdrmengine/cdm/core/src/client_identification.cpp @@ -379,10 +379,30 @@ bool ClientIdentification::GetProvisioningTokenType( *token_type = video_widevine::ClientIdentification::OEM_DEVICE_CERTIFICATE; return true; - case kClientTokenBootCertChain: - *token_type = - video_widevine::ClientIdentification::BOOT_CERTIFICATE_CHAIN; + case kClientTokenBootCertChain: { + OEMCrypto_BCCType bcc_type; + const CdmResponseType result = + crypto_session_->GetProvisioning40TokenType(&bcc_type); + if (result == NOT_IMPLEMENTED_ERROR) { + // Default to CBOR BCC for OEMCrypto that doesn't support GetBCCType(). + *token_type = + video_widevine::ClientIdentification::BOOT_CERTIFICATE_CHAIN; + return true; + } + if (result != NO_ERROR) return false; + if (bcc_type == OEMCrypto_CBOR) { + *token_type = + video_widevine::ClientIdentification::BOOT_CERTIFICATE_CHAIN; + } else if (bcc_type == OEMCrypto_X509) { + *token_type = + video_widevine::ClientIdentification::BOOT_CERTIFICATE_CHAIN_X509; + } else { + // shouldn't happen + LOGE("Unexpected BCC type: %d", static_cast(bcc_type)); + return false; + } return true; + } case kClientTokenDrmCert: // TODO: b/305093063 - Add token for DRM reprovisioning requests. case kClientTokenDrmReprovisioning: diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 315225e6..eb1efb39 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -667,6 +667,24 @@ CdmResponseType CryptoSession::GetProvisioningToken( return status; } +CdmResponseType CryptoSession::GetProvisioning40TokenType( + OEMCrypto_BCCType* bcc_type) { + RETURN_IF_NOT_OPEN(CRYPTO_SESSION_NOT_OPEN); + return GetProvisioning40TokenType(requested_security_level_, bcc_type); +} + +CdmResponseType CryptoSession::GetProvisioning40TokenType( + RequestedSecurityLevel requested_security_level, + OEMCrypto_BCCType* bcc_type) { + RETURN_IF_NULL(bcc_type, PARAMETER_NULL); + RETURN_IF_UNINITIALIZED(CRYPTO_SESSION_NOT_INITIALIZED); + OEMCryptoResult sts = WithOecReadLock("GetBCCType", [&] { + return OEMCrypto_GetBCCType(requested_security_level, bcc_type); + }); + return MapOEMCryptoResult(sts, UNKNOWN_CLIENT_TOKEN_TYPE, + "GetProvisioning40TokenType"); +} + CdmSecurityLevel CryptoSession::GetSecurityLevel() { LOGV("Getting security level"); RETURN_IF_NOT_OPEN(kSecurityLevelUninitialized); @@ -3450,40 +3468,40 @@ CdmResponseType CryptoSession::LoadOtaProvisioning( } template -auto CryptoSession::WithStaticFieldWriteLock(const char* tag, Func body) - -> decltype(body()) { +auto CryptoSession::WithStaticFieldWriteLock(const char* tag, + Func body) -> decltype(body()) { LOGV("Static field write lock: %s", tag); std::unique_lock auto_lock(static_field_mutex_); return body(); } template -auto CryptoSession::WithStaticFieldReadLock(const char* tag, Func body) - -> decltype(body()) { +auto CryptoSession::WithStaticFieldReadLock(const char* tag, + Func body) -> decltype(body()) { LOGV("Static field read lock: %s", tag); wvutil::shared_lock auto_lock(static_field_mutex_); return body(); } template -auto CryptoSession::WithOecWriteLock(const char* tag, Func body) - -> decltype(body()) { +auto CryptoSession::WithOecWriteLock(const char* tag, + Func body) -> decltype(body()) { LOGV("OEMCrypto write lock: %s", tag); std::unique_lock auto_lock(oem_crypto_mutex_); return body(); } template -auto CryptoSession::WithOecReadLock(const char* tag, Func body) - -> decltype(body()) { +auto CryptoSession::WithOecReadLock(const char* tag, + Func body) -> decltype(body()) { LOGV("OEMCrypto read lock: %s", tag); wvutil::shared_lock auto_lock(oem_crypto_mutex_); return body(); } template -auto CryptoSession::WithOecSessionLock(const char* tag, Func body) - -> decltype(body()) { +auto CryptoSession::WithOecSessionLock(const char* tag, + Func body) -> decltype(body()) { LOGV("OEMCrypto session lock: %s", tag); wvutil::shared_lock oec_auto_lock(oem_crypto_mutex_); std::unique_lock session_auto_lock(oem_crypto_session_mutex_); diff --git a/libwvdrmengine/cdm/core/src/license_protocol.proto b/libwvdrmengine/cdm/core/src/license_protocol.proto index 35e61e4a..70c778c3 100644 --- a/libwvdrmengine/cdm/core/src/license_protocol.proto +++ b/libwvdrmengine/cdm/core/src/license_protocol.proto @@ -1096,7 +1096,10 @@ message ClientIdentification { DRM_DEVICE_CERTIFICATE = 1; REMOTE_ATTESTATION_CERTIFICATE = 2; OEM_DEVICE_CERTIFICATE = 3; + // Boot certificate chain in CBOR format. BOOT_CERTIFICATE_CHAIN = 4; + // Boot certificate chain in X509 format. + BOOT_CERTIFICATE_CHAIN_X509 = 5; } message NameValue { diff --git a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp index 1569aa5b..7a351380 100644 --- a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp +++ b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp @@ -1567,10 +1567,13 @@ OEMCrypto_ProvisioningMethod OEMCrypto_GetProvisioningMethod( return fcn->GetProvisioningMethod(); } -OEMCryptoResult OEMCrypto_GetBCCType(OEMCrypto_BCCType* bcc_type) { +OEMCryptoResult OEMCrypto_GetBCCType(wvcdm::RequestedSecurityLevel level, + OEMCrypto_BCCType* bcc_type) { if (!gAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; - const FunctionPointers* fcn = gAdapter->GetFunctionPointers(kLevelDefault); + const FunctionPointers* fcn = gAdapter->GetFunctionPointers(level); if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION; + if (fcn->security_level != wvcdm::kSecurityLevelL1) + return OEMCrypto_ERROR_NOT_IMPLEMENTED; if (fcn->GetBCCType == nullptr) return OEMCrypto_ERROR_NOT_IMPLEMENTED; return fcn->GetBCCType(bcc_type); }