From f6f5099604411a7127aaa8178f4035945492290e Mon Sep 17 00:00:00 2001 From: Alex Dale Date: Thu, 18 Feb 2021 19:53:12 -0800 Subject: [PATCH 1/5] Restructed reference root of trust (2/3 DRM Cert) [ Merge of http://go/wvgerrit/115551 ] This change is the second part of a three part change for restructing the root of trust used by the reference implementation. The use of RSA_shared_ptr has been replaced with the standard library std::shared_ptr using the RsaPrivateKey wrapper class. The AuthenticationRoot class now uses this for the built-in DRM cert key. RSA decryption and signature operations within the session context are now performed the RsaPrivateKey class. This has reduced the code size and complexity within the reference and testbed, focusing their implementation on key policy and less on mechanics. Bug: 168544740 Bug: 135283522 Test: oemcrypto_unittests ce_cdm_tests Change-Id: Ic743a529a9858f3182290d8bcf5e1633737b005b --- .../oemcrypto/ref/src/oemcrypto_auth_ref.cpp | 21 +- .../oemcrypto/ref/src/oemcrypto_auth_ref.h | 26 +- ...crypto_engine_device_properties_prov30.cpp | 2 +- .../ref/src/oemcrypto_engine_ref.cpp | 6 +- .../oemcrypto/ref/src/oemcrypto_engine_ref.h | 5 +- .../oemcrypto/ref/src/oemcrypto_ref.cpp | 98 +++---- .../oemcrypto/ref/src/oemcrypto_rsa_key.cpp | 1 - .../ref/src/oemcrypto_rsa_key_shared.cpp | 101 ------- .../ref/src/oemcrypto_rsa_key_shared.h | 42 --- .../oemcrypto/ref/src/oemcrypto_session.cpp | 264 ++++++------------ .../oemcrypto/ref/src/oemcrypto_session.h | 79 +++--- 11 files changed, 187 insertions(+), 458 deletions(-) delete mode 100644 libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.cpp delete mode 100644 libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.h diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.cpp index e6ab7cec..984de937 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.cpp @@ -187,7 +187,6 @@ bool AuthenticationRoot::Initialize(OEMCrypto_ProvisioningMethod method) { // If provisioning method is something other than ProvisioningError // indicates it has already been initialized before. Must // existing data. - rsa_key_set_ = false; rsa_key_.reset(); test_rsa_key_.reset(); keybox_.reset(); @@ -196,8 +195,11 @@ bool AuthenticationRoot::Initialize(OEMCrypto_ProvisioningMethod method) { prov_method_ = method; switch (method) { case OEMCrypto_DrmCertificate: { - rsa_key_set_ = rsa_key_.LoadPkcs8RsaKey(kPrivateKey, kPrivateKeySize); - if (!rsa_key_set_) { + std::unique_ptr key = + RsaPrivateKey::Load(kPrivateKey, kPrivateKeySize); + if (key) { + rsa_key_ = std::move(key); + } else { // This error message is OK in unit tests which use test certificate. LOGE( "FATAL ERROR: Platform uses a baked-in certificate instead of a " @@ -222,7 +224,7 @@ bool AuthenticationRoot::Initialize(OEMCrypto_ProvisioningMethod method) { bool AuthenticationRoot::IsValid() const { switch (prov_method_) { case OEMCrypto_DrmCertificate: { - return rsa_key_set_ && HasDeviceKey(); + return HasDrmCertKey() && HasDeviceKey(); } case OEMCrypto_Keybox: { return HasDeviceKey(); @@ -324,17 +326,18 @@ OEMCryptoResult AuthenticationRoot::LoadTestRsaKey() { LOGE("System does not support DRM certificates"); return OEMCrypto_ERROR_NOT_IMPLEMENTED; } - if (test_rsa_key_.get() != nullptr) { + if (test_rsa_key_) { LOGE("Test RSA key is already loaded"); return OEMCrypto_ERROR_INSUFFICIENT_RESOURCES; } - if (!test_rsa_key_.LoadPkcs8RsaKey( - kTestRSAPKCS8PrivateKeyInfo2_2048, - sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048))) { + std::unique_ptr key = + RsaPrivateKey::Load(kTestRSAPKCS8PrivateKeyInfo2_2048, + sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048)); + if (!key) { LOGE("Failed to load test RSA key"); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - rsa_key_set_ = true; + test_rsa_key_ = std::move(key); return OEMCrypto_SUCCESS; } diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.h index 3650c557..9050b983 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.h @@ -8,17 +8,14 @@ #define OEMCRYPTO_AUTH_REF_H_ #include + #include #include -#include - #include "OEMCryptoCENC.h" // Needed for enums only. #include "disallow_copy_and_assign.h" -#include "oemcrypto_key_ref.h" #include "oemcrypto_keybox_ref.h" -#include "oemcrypto_rsa_key_shared.h" -#include "oemcrypto_types.h" +#include "oemcrypto_rsa_key.h" namespace wvoec_ref { // The AuthenticationRoot class contains the OEMCrypto information @@ -69,13 +66,13 @@ class AuthenticationRoot { // Returns the shared RSA private key from the built-in DRM // Certificate. - RSA_shared_ptr& SharedRsaKey() { - return test_rsa_key_.get() != nullptr ? test_rsa_key_ : rsa_key_; + std::shared_ptr ShareDrmCertKey() { + return test_rsa_key_ ? test_rsa_key_ : rsa_key_; } - RSA* rsa_key() { - return test_rsa_key_.get() != nullptr ? test_rsa_key_.get() - : rsa_key_.get(); + RsaPrivateKey* DrmCertKey() const { + return test_rsa_key_ ? test_rsa_key_.get() : rsa_key_.get(); } + bool HasDrmCertKey() const { return test_rsa_key_ || rsa_key_; } // Loads the system's built-in RSA key. Only implemented for // devices that are that pre-provisioned with a built-in DRM @@ -144,11 +141,10 @@ class AuthenticationRoot { OEMCrypto_ProvisioningMethod prov_method_ = OEMCrypto_ProvisioningError; // DRM certificate. - // TODO(b/168544740): Remove |rsa_key_set_| when RSA_shared_ptr has - // been replaced with scoped RsaPrivateKey. - bool rsa_key_set_ = false; - RSA_shared_ptr rsa_key_; // If no keybox, this is baked in certificate. - RSA_shared_ptr test_rsa_key_; + // If no keybox, this is the private key of the baked-in DRM + // Certificate. + std::shared_ptr rsa_key_; + std::shared_ptr test_rsa_key_; // Keybox data. std::unique_ptr keybox_; diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp index 6fd2269f..3b17bb63 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp @@ -65,7 +65,7 @@ class Prov30CryptoEngine : public CryptoEngine { return OEMCrypto_ERROR_SHORT_BUFFER; } memcpy(public_cert, kOEMPublicCert, kOEMPublicCertSize); - if (!session->LoadRSAKey(kOEMPrivateKey, kOEMPrivateKeySize)) { + if (!session->LoadRsaDrmKey(kOEMPrivateKey, kOEMPrivateKeySize)) { LOGE("Private RSA Key did not load correctly."); return OEMCrypto_ERROR_INVALID_RSA_KEY; } diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.cpp index e85cebff..9a6f1d47 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.cpp @@ -20,7 +20,6 @@ #include "keys.h" #include "log.h" #include "oemcrypto_key_ref.h" -#include "oemcrypto_rsa_key_shared.h" #include "string_conversions.h" namespace { @@ -81,7 +80,10 @@ SessionId CryptoEngine::OpenSession() { } SessionContext* CryptoEngine::MakeSession(SessionId sid) { - return new SessionContext(this, sid, root_of_trust_.SharedRsaKey()); + if (root_of_trust_.HasDrmCertKey()) { + return new SessionContext(this, sid, root_of_trust_.ShareDrmCertKey()); + } + return new SessionContext(this, sid); } UsageTable* CryptoEngine::MakeUsageTable() { return new UsageTable(this); } diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h index 394c17e7..70613aff 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h @@ -8,19 +8,16 @@ #define REF_OEMCRYPTO_ENGINE_REF_H_ #include -#include + #include #include #include #include -#include - #include "OEMCryptoCENC.h" #include "file_store.h" #include "oemcrypto_auth_ref.h" #include "oemcrypto_key_ref.h" -#include "oemcrypto_rsa_key_shared.h" #include "oemcrypto_session.h" #include "oemcrypto_types.h" #include "oemcrypto_usage_table_ref.h" diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp index 68728809..09b78315 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp @@ -172,11 +172,8 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateDerivedKeys( enc_key_context, enc_key_context + enc_key_context_length); // Generate mac and encryption keys for current session context - if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), mac_ctx_str, - enc_ctx_str)) { - return OEMCrypto_ERROR_UNKNOWN_FAILURE; - } - return OEMCrypto_SUCCESS; + return session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), mac_ctx_str, + enc_ctx_str); } OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session, @@ -893,8 +890,10 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( return OEMCrypto_ERROR_INVALID_NONCE; } - if (!session_ctx->InstallRSAEncryptedKey(encrypted_message_key, - encrypted_message_key_length)) { + const std::vector enc_encryption_key( + encrypted_message_key, + encrypted_message_key + encrypted_message_key_length); + if (!session_ctx->InstallRSAEncryptedKey(enc_encryption_key)) { LOGE( "OEMCrypto_RewrapDeviceRSAKey30: " "Error loading encrypted_message_key."); @@ -904,11 +903,11 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( // Decrypt RSA key. std::vector pkcs8_rsa_key(enc_rsa_key_length); if (!session_ctx->DecryptRSAKey(enc_rsa_key, enc_rsa_key_length, - enc_rsa_key_iv, &pkcs8_rsa_key[0])) { + enc_rsa_key_iv, pkcs8_rsa_key.data())) { return OEMCrypto_ERROR_INVALID_RSA_KEY; } - if (!session_ctx->LoadRSAKey(&pkcs8_rsa_key[0], enc_rsa_key_length)) { - LOGE("[OEMCrypto_RewrapDeviceRSAKey30(): Failed to LoadRSAKey."); + if (!session_ctx->LoadRsaDrmKey(pkcs8_rsa_key.data(), enc_rsa_key_length)) { + LOGE("Failed to load RSA DRM key"); return OEMCrypto_ERROR_INVALID_RSA_KEY; } @@ -926,23 +925,24 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( const std::vector context( wrapped->context, wrapped->context + sizeof(wrapped->context)); // Generate mac and encryption keys for encrypting the signature. - if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, - context)) { + const OEMCryptoResult derive_key_result = + session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, context); + if (derive_key_result != OEMCrypto_SUCCESS) { LOGE("[_RewrapDeviceRSAKey30(): DeriveKeys failed."); - return OEMCrypto_ERROR_UNKNOWN_FAILURE; + return derive_key_result; } // Encrypt rsa key with keybox. - if (!session_ctx->EncryptRSAKey(&pkcs8_rsa_key[0], enc_rsa_key_length, + if (!session_ctx->EncryptRSAKey(pkcs8_rsa_key.data(), enc_rsa_key_length, wrapped->iv, wrapped->enc_rsa_key)) { LOGE("[_RewrapDeviceRSAKey30(): EncrypteRSAKey failed."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } const size_t buffer_size = enc_rsa_key_length + sizeof(WrappedRSAKey); - // The wrapped keybox must be signed with the same key we verify with. I'll - // pick the server key, so I don't have to modify LoadRSAKey. + // The wrapped keybox must be signed with the same key we verify with. + // Reference implementation uses the server key. unsigned int sig_length = sizeof(wrapped->signature); - if (!HMAC(EVP_sha256(), &session_ctx->mac_key_server()[0], + if (!HMAC(EVP_sha256(), session_ctx->mac_key_server().data(), session_ctx->mac_key_server().size(), wrapped->context, buffer_size - sizeof(wrapped->signature), wrapped->signature, &sig_length)) { @@ -1006,10 +1006,10 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey( // Decrypt RSA key and verify it. std::vector pkcs8_rsa_key(enc_rsa_key_length); if (!session_ctx->DecryptRSAKey(enc_rsa_key, enc_rsa_key_length, - enc_rsa_key_iv, &pkcs8_rsa_key[0])) { + enc_rsa_key_iv, pkcs8_rsa_key.data())) { return OEMCrypto_ERROR_INVALID_RSA_KEY; } - if (!session_ctx->LoadRSAKey(&pkcs8_rsa_key[0], enc_rsa_key_length)) { + if (!session_ctx->LoadRsaDrmKey(pkcs8_rsa_key.data(), enc_rsa_key_length)) { return OEMCrypto_ERROR_INVALID_RSA_KEY; } @@ -1025,21 +1025,22 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey( const std::vector context( wrapped->context, wrapped->context + sizeof(wrapped->context)); // Generate mac and encryption keys for encrypting the signature. - if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, - context)) { - return OEMCrypto_ERROR_UNKNOWN_FAILURE; + const OEMCryptoResult derive_key_result = + session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, context); + if (derive_key_result != OEMCrypto_SUCCESS) { + return derive_key_result; } // Encrypt rsa key with keybox. - if (!session_ctx->EncryptRSAKey(&pkcs8_rsa_key[0], enc_rsa_key_length, + if (!session_ctx->EncryptRSAKey(pkcs8_rsa_key.data(), enc_rsa_key_length, wrapped->iv, wrapped->enc_rsa_key)) { return OEMCrypto_ERROR_UNKNOWN_FAILURE; } const size_t buffer_size = enc_rsa_key_length + sizeof(WrappedRSAKey); - // The wrapped keybox must be signed with the same key we verify with. I'll - // pick the server key, so I don't have to modify LoadRSAKey. + // The wrapped keybox must be signed with the same key we verify with. + // Reference implementation uses the server key. unsigned int sig_length = sizeof(wrapped->signature); - if (!HMAC(EVP_sha256(), &session_ctx->mac_key_server()[0], + if (!HMAC(EVP_sha256(), session_ctx->mac_key_server().data(), session_ctx->mac_key_server().size(), wrapped->context, buffer_size - sizeof(wrapped->signature), wrapped->signature, &sig_length)) { @@ -1173,9 +1174,10 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadDRMPrivateKey( const std::vector context( wrapped->context, wrapped->context + sizeof(wrapped->context)); // Generate mac and encryption keys for encrypting the signature. - if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, - context)) { - return OEMCrypto_ERROR_UNKNOWN_FAILURE; + const OEMCryptoResult derive_key_result = + session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, context); + if (derive_key_result != OEMCrypto_SUCCESS) { + return derive_key_result; } // verify signature. if (!session_ctx->ValidateMessage( @@ -1189,7 +1191,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadDRMPrivateKey( sizeof(wrapped->signature)); size_t enc_rsa_key_length = wrapped_rsa_key_length - sizeof(WrappedRSAKey); if (!session_ctx->DecryptRSAKey(wrapped->enc_rsa_key, enc_rsa_key_length, - wrapped->iv, &pkcs8_rsa_key[0])) { + wrapped->iv, pkcs8_rsa_key.data())) { return OEMCrypto_ERROR_INVALID_RSA_KEY; } size_t padding = pkcs8_rsa_key[enc_rsa_key_length - 1]; @@ -1198,7 +1200,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadDRMPrivateKey( padding = 0; } size_t rsa_key_length = enc_rsa_key_length - padding; - if (!session_ctx->LoadRSAKey(&pkcs8_rsa_key[0], rsa_key_length)) { + if (!session_ctx->LoadRsaDrmKey(pkcs8_rsa_key.data(), rsa_key_length)) { return OEMCrypto_ERROR_INVALID_RSA_KEY; } return OEMCrypto_SUCCESS; @@ -1231,22 +1233,8 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateRSASignature( LOGE("[OEMCrypto_GenerateRSASignature(): ERROR_INVALID_SESSION]"); return OEMCrypto_ERROR_INVALID_SESSION; } - - size_t required_size = session_ctx->RSASignatureSize(); - if (*signature_length < required_size) { - *signature_length = required_size; - return OEMCrypto_ERROR_SHORT_BUFFER; - } - - if (message == nullptr || message_length == 0 || signature == nullptr || - signature_length == 0) { - LOGE("[OEMCrypto_GenerateRSASignature(): OEMCrypto_ERROR_INVALID_CONTEXT]"); - return OEMCrypto_ERROR_INVALID_CONTEXT; - } - - OEMCryptoResult sts = session_ctx->GenerateRSASignature( - message, message_length, signature, signature_length, padding_scheme); - return sts; + return session_ctx->GenerateRSASignature(message, message_length, signature, + signature_length, padding_scheme); } OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey( @@ -1259,27 +1247,22 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey( return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if (!crypto_engine->ValidRootOfTrust()) { - LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_KEYBOX_INVALID]"); + LOGE("[OEMCrypto_DeriveKeysFromSessionKey(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; } if (mac_key_context_length > kMaxContextKeyLength || enc_key_context_length > kMaxContextKeyLength || enc_session_key_length > kMaxContextKeyLength) { - LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_BUFFER_TOO_LARGE]"); + LOGE("[OEMCrypto_DeriveKeysFromSessionKey(): ERROR_BUFFER_TOO_LARGE]"); return OEMCrypto_ERROR_BUFFER_TOO_LARGE; } SessionContext* session_ctx = crypto_engine->FindSession(session); if (session_ctx == nullptr || !session_ctx->isValid()) { - LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_INVALID_SESSION]"); + LOGE("[OEMCrypto_DeriveKeysFromSessionKey(): ERROR_INVALID_SESSION]"); return OEMCrypto_ERROR_INVALID_SESSION; } - if (session_ctx->allowed_schemes() != kSign_RSASSA_PSS) { - LOGE("[OEMCrypto_GenerateDerivedKeys(): x509 key used to derive keys]"); - return OEMCrypto_ERROR_INVALID_RSA_KEY; - } - const std::vector ssn_key_str( enc_session_key, enc_session_key + enc_session_key_length); const std::vector mac_ctx_str( @@ -1288,10 +1271,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey( enc_key_context, enc_key_context + enc_key_context_length); // Generate mac and encryption keys for current session context - if (!session_ctx->RSADeriveKeys(ssn_key_str, mac_ctx_str, enc_ctx_str)) { - return OEMCrypto_ERROR_UNKNOWN_FAILURE; - } - return OEMCrypto_SUCCESS; + return session_ctx->RSADeriveKeys(ssn_key_str, mac_ctx_str, enc_ctx_str); } OEMCRYPTO_API uint32_t OEMCrypto_APIVersion() { diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key.cpp index 71aea9b4..6a9c2af2 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key.cpp @@ -993,7 +993,6 @@ bool RsaPrivateKey::InitFromBuffer(const uint8_t* buffer, size_t length) { } // Step 3: Verify field width. const int bits = RSA_bits(key.get()); - LOGD("Loaded RSA private key size: bits = %d", bits); field_size_ = RealBitSizeToFieldSize(bits); if (field_size_ == kRsaFieldUnknown) { LOGE("Unsupported RSA key size: bits = %d", bits); diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.cpp deleted file mode 100644 index 6c73ad81..00000000 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary -// source code may only be used and distributed under the Widevine Master -// License Agreement. -// -// Reference implementation of OEMCrypto APIs -// -#include "oemcrypto_rsa_key_shared.h" - -#include - -#include -#include -#include -#include -#include - -#include "log.h" - -namespace wvoec_ref { - -void dump_boringssl_error() { - int count = 0; - while (unsigned long err = ERR_get_error()) { - count++; - char buffer[120]; - ERR_error_string_n(err, buffer, sizeof(buffer)); - LOGE("BoringSSL Error %d -- %lu -- %s", count, err, buffer); - } - LOGE("Reported %d BoringSSL Errors", count); -} - -void RSA_shared_ptr::reset() { - if (rsa_key_ && key_owned_) { - RSA_free(rsa_key_); - } - key_owned_ = false; - rsa_key_ = nullptr; -} - -bool RSA_shared_ptr::LoadPkcs8RsaKey(const uint8_t* buffer, size_t length) { - assert(buffer != nullptr); - reset(); - uint8_t* pkcs8_rsa_key = const_cast(buffer); - BIO* bio = BIO_new_mem_buf(pkcs8_rsa_key, length); - if (bio == nullptr) { - LOGE("[LoadPkcs8RsaKey(): Could not allocate bio buffer]"); - return false; - } - bool success = true; - PKCS8_PRIV_KEY_INFO* pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, nullptr); - if (pkcs8_pki == nullptr) { - BIO_reset(bio); - pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, nullptr); - if (pkcs8_pki == nullptr) { - LOGE("[LoadPkcs8RsaKey(): d2i_PKCS8_PRIV_KEY_INFO_bio returned nullptr]"); - dump_boringssl_error(); - success = false; - } - } - EVP_PKEY* evp = nullptr; - if (success) { - evp = EVP_PKCS82PKEY(pkcs8_pki); - if (evp == nullptr) { - LOGE("[LoadPkcs8RsaKey(): EVP_PKCS82PKEY returned nullptr]"); - dump_boringssl_error(); - success = false; - } - } - if (success) { - rsa_key_ = EVP_PKEY_get1_RSA(evp); - if (rsa_key_ == nullptr) { - LOGE("[LoadPkcs8RsaKey(): PrivateKeyInfo did not contain an RSA key]"); - success = false; - } - key_owned_ = true; - } - if (evp != nullptr) { - EVP_PKEY_free(evp); - } - if (pkcs8_pki != nullptr) { - PKCS8_PRIV_KEY_INFO_free(pkcs8_pki); - } - BIO_free(bio); - if (!success) { - return false; - } - switch (RSA_check_key(rsa_key_)) { - case 1: // valid. - return true; - case 0: // not valid. - LOGE("[LoadPkcs8RsaKey(): rsa key not valid]"); - dump_boringssl_error(); - return false; - default: // -1 == check failed. - LOGE("[LoadPkcs8RsaKey(): error checking rsa key]"); - dump_boringssl_error(); - return false; - } -} - -} // namespace wvoec_ref diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.h deleted file mode 100644 index 98ea154e..00000000 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary -// source code may only be used and distributed under the Widevine Master -// License Agreement. -// -// Reference implementation of OEMCrypto APIs -// -#ifndef OEMCRYPTO_RSA_KEY_SHARED_H_ -#define OEMCRYPTO_RSA_KEY_SHARED_H_ - -#include - -#include - -namespace wvoec_ref { - -// Shared pointer with specialized destructor. This pointer is only shared -// from a CryptoEngine to a Session -- so we don't have to use full reference -// counting. -class RSA_shared_ptr { - public: - RSA_shared_ptr() : rsa_key_(nullptr), key_owned_(false) {} - ~RSA_shared_ptr() { reset(); }; - // Explicitly allow copy as share. - explicit RSA_shared_ptr(const RSA_shared_ptr& other) : - rsa_key_(other.rsa_key_), key_owned_(false) {} - RSA* get() { return rsa_key_; } - void reset(); - bool LoadPkcs8RsaKey(const uint8_t* buffer, size_t length); - - private: - void operator=(const RSA_shared_ptr); // disallow assign. - - RSA* rsa_key_; - bool key_owned_; -}; - -// Log errors from BoringSSL. -void dump_boringssl_error(); - -} // namespace wvoec_ref - -#endif // OEMCRYPTO_RSA_KEY_SHARED_H_ diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp index ed58fcf0..69e219f6 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp @@ -25,20 +25,17 @@ #include #include "advance_iv_ctr.h" -#include "disallow_copy_and_assign.h" #include "keys.h" #include "log.h" #include "odk.h" #include "oemcrypto_engine_ref.h" #include "oemcrypto_key_ref.h" -#include "oemcrypto_rsa_key_shared.h" #include "oemcrypto_types.h" #include "platform.h" #include "string_conversions.h" #include "wvcrc32.h" -static const int kPssSaltLength = 20; - +namespace wvoec_ref { namespace { // Increment counter for AES-CTR. The CENC spec specifies we increment only @@ -66,11 +63,8 @@ void advance_dest_buffer(OEMCrypto_DestBufferDesc* dest_buffer, size_t bytes) { break; } } - } // namespace -namespace wvoec_ref { - /***************************************/ class ContentKeysContext : public SessionContextKeys { @@ -181,31 +175,17 @@ EntitlementKey* EntitlementKeysContext::GetEntitlementKey( /***************************************/ -SessionContext::SessionContext(CryptoEngine* ce, SessionId sid, - const RSA_shared_ptr& rsa_key) - : valid_(true), - ce_(ce), - id_(sid), - current_content_key_(nullptr), - session_keys_(nullptr), - license_request_hash_(), - rsa_key_(rsa_key), - allowed_schemes_(kSign_RSASSA_PSS), - decrypt_started_(false), - timer_limits_(), - clock_values_(), - usage_entry_(nullptr), - srm_requirements_status_(NoSRMVersion), - usage_entry_status_(kNoUsageEntry), - compute_hash_(false), - current_hash_(0), - bad_frame_number_(0), - hash_error_(OEMCrypto_SUCCESS), - state_nonce_created_(false), - state_request_signed_(false), - state_response_loaded_(false) { +SessionContext::SessionContext(CryptoEngine* ce, SessionId sid) + : valid_(ce != nullptr), ce_(ce), id_(sid) { ODK_InitializeSessionValues(&timer_limits_, &clock_values_, &nonce_values_, CryptoEngine::kApiVersion, sid); + memset(license_request_hash_, 0, sizeof(license_request_hash_)); +} + +SessionContext::SessionContext(CryptoEngine* ce, SessionId sid, + std::shared_ptr&& rsa_key) + : SessionContext(ce, sid) { + rsa_key_ = std::move(rsa_key); } SessionContext::~SessionContext() {} @@ -258,27 +238,28 @@ bool SessionContext::DeriveKey(const std::vector& key, return true; } -bool SessionContext::DeriveKeys(const std::vector& master_key, - const std::vector& mac_key_context, - const std::vector& enc_key_context) { +OEMCryptoResult SessionContext::DeriveKeys( + const std::vector& master_key, + const std::vector& mac_key_context, + const std::vector& enc_key_context) { // Generate derived key for mac key std::vector mac_key_server; std::vector mac_key_client; std::vector mac_key_part2; if (!DeriveKey(master_key, mac_key_context, 1, &mac_key_server)) { - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if (!DeriveKey(master_key, mac_key_context, 2, &mac_key_part2)) { - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } mac_key_server.insert(mac_key_server.end(), mac_key_part2.begin(), mac_key_part2.end()); if (!DeriveKey(master_key, mac_key_context, 3, &mac_key_client)) { - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if (!DeriveKey(master_key, mac_key_context, 4, &mac_key_part2)) { - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } mac_key_client.insert(mac_key_client.end(), mac_key_part2.begin(), mac_key_part2.end()); @@ -286,48 +267,31 @@ bool SessionContext::DeriveKeys(const std::vector& master_key, // Generate derived key for encryption key std::vector enc_key; if (!DeriveKey(master_key, enc_key_context, 1, &enc_key)) { - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } set_mac_key_server(mac_key_server); set_mac_key_client(mac_key_client); set_encryption_key(enc_key); - return true; + return OEMCrypto_SUCCESS; } -bool SessionContext::RSADeriveKeys( +OEMCryptoResult SessionContext::RSADeriveKeys( const std::vector& enc_session_key, const std::vector& mac_key_context, const std::vector& enc_key_context) { - if (!rsa_key()) { - LOGE("[RSADeriveKeys(): no RSA key set]"); - return false; + if (!rsa_key_) { + LOGE("No RSA key set"); + return OEMCrypto_ERROR_DEVICE_NOT_RSA_PROVISIONED; } - const size_t actual_key_size = static_cast(RSA_size(rsa_key())); - if (enc_session_key.size() != actual_key_size) { - LOGE( - "[RSADeriveKeys(): encrypted session key wrong size: %zu, expected " - "%zu]", - enc_session_key.size(), actual_key_size); - dump_boringssl_error(); - return false; + if (!(rsa_key_->allowed_schemes() & kSign_RSASSA_PSS)) { + LOGE("Key cannot be used for session key decryption"); + return OEMCrypto_ERROR_INVALID_RSA_KEY; } - session_key_.resize(RSA_size(rsa_key())); - const int decrypted_size = - RSA_private_decrypt(enc_session_key.size(), &enc_session_key[0], - &session_key_[0], rsa_key(), RSA_PKCS1_OAEP_PADDING); - if (-1 == decrypted_size) { - LOGE("[RSADeriveKeys(): error decrypting session key.]"); - dump_boringssl_error(); - return false; - } - session_key_.resize(decrypted_size); - if (decrypted_size != static_cast(wvoec::KEY_SIZE)) { - LOGE("[RSADeriveKeys(): error. Session key is wrong size: %d.]", - decrypted_size); - dump_boringssl_error(); - session_key_.clear(); - return false; + session_key_ = rsa_key_->DecryptSessionKey(enc_session_key); + if (session_key_.empty()) { + LOGE("Failed decrypt session key"); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } return DeriveKeys(session_key_, mac_key_context, enc_key_context); } @@ -336,8 +300,13 @@ OEMCryptoResult SessionContext::PrepAndSignLicenseRequest( uint8_t* message, size_t message_length, size_t* core_message_length, uint8_t* signature, size_t* signature_length) { if (signature_length == nullptr || core_message_length == nullptr) { + LOGE("Output length parameters are null"); return OEMCrypto_ERROR_INVALID_CONTEXT; } + if (!rsa_key_) { + LOGE("No DRM key available for signature"); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } const size_t required_signature_size = CertSignatureSize(); OEMCryptoResult result = ODK_PrepareCoreLicenseRequest( message, message_length, core_message_length, &nonce_values_); @@ -424,6 +393,10 @@ OEMCryptoResult SessionContext::PrepAndSignProvisioningRequest( if (signature_length == nullptr || core_message_length == nullptr) { return OEMCrypto_ERROR_INVALID_CONTEXT; } + if (!rsa_key_ && mac_key_client_.empty()) { + LOGE("Session cannot sign request"); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } if (state_request_signed_) { LOGE("Attempt to sign prov request after license request"); return OEMCrypto_ERROR_UNKNOWN_FAILURE; @@ -488,29 +461,20 @@ OEMCryptoResult SessionContext::GenerateSignature(const uint8_t* message, return OEMCrypto_ERROR_UNKNOWN_FAILURE; } -// This is ussd when the device is a cast receiver. -size_t SessionContext::RSASignatureSize() { - if (!rsa_key()) { - LOGE("no RSA key set"); +size_t SessionContext::CertSignatureSize() const { + if (!rsa_key_) { + LOGE("No RSA key set"); return 0; } - return static_cast(RSA_size(rsa_key())); + return rsa_key_->SignatureSize(); } -size_t SessionContext::CertSignatureSize() { - // TODO(b/67735947): Add ECC cert support. - if (!rsa_key()) { - LOGE("No private key set"); - return 0; - } - return static_cast(RSA_size(rsa_key())); -} - -size_t SessionContext::ROTSignatureSize() { +size_t SessionContext::ROTSignatureSize() const { if (ce_->config_provisioning_method() == OEMCrypto_Keybox) return SHA256_DIGEST_LENGTH; - if (ce_->config_provisioning_method() == OEMCrypto_OEMCertificate) + if (ce_->config_provisioning_method() == OEMCrypto_OEMCertificate) { return CertSignatureSize(); + } LOGE("Bad prov method = %d", static_cast(ce_->config_provisioning_method())); return 0; @@ -519,92 +483,27 @@ size_t SessionContext::ROTSignatureSize() { OEMCryptoResult SessionContext::GenerateCertSignature( const uint8_t* message, size_t message_length, uint8_t* signature, size_t* signature_length) { - // TODO(b/67735947): Add ECC cert support. - if (message == nullptr || message_length == 0 || signature == nullptr || - signature_length == 0) { - LOGE("OEMCrypto_ERROR_INVALID_CONTEXT"); - return OEMCrypto_ERROR_INVALID_CONTEXT; - } - if (!rsa_key()) { + if (!rsa_key_) { LOGE("No RSA key set"); return OEMCrypto_ERROR_INVALID_RSA_KEY; } - if (*signature_length < static_cast(RSA_size(rsa_key()))) { - *signature_length = CertSignatureSize(); - return OEMCrypto_ERROR_SHORT_BUFFER; - } - if (allowed_schemes_ != kSign_RSASSA_PSS) { - LOGE("Message signing not allowed"); - return OEMCrypto_ERROR_INVALID_RSA_KEY; - } - - // Hash the message using SHA1. - uint8_t hash[SHA_DIGEST_LENGTH]; - if (!SHA1(message, message_length, hash)) { - LOGE("Error creating signature hash"); - dump_boringssl_error(); - return OEMCrypto_ERROR_UNKNOWN_FAILURE; - } - - // Add PSS padding. - std::vector padded_digest(*signature_length); - int status = RSA_padding_add_PKCS1_PSS_mgf1( - rsa_key(), &padded_digest[0], hash, EVP_sha1(), nullptr, kPssSaltLength); - if (status == -1) { - LOGE("Error padding hash"); - dump_boringssl_error(); - return OEMCrypto_ERROR_UNKNOWN_FAILURE; - } - - // Encrypt PSS padded digest. - status = RSA_private_encrypt(*signature_length, &padded_digest[0], signature, - rsa_key(), RSA_NO_PADDING); - if (status == -1) { - LOGE("Error in private encrypt"); - dump_boringssl_error(); - return OEMCrypto_ERROR_UNKNOWN_FAILURE; - } - return OEMCrypto_SUCCESS; + return rsa_key_->GenerateSignature(message, message_length, kRsaPssDefault, + signature, signature_length); } OEMCryptoResult SessionContext::GenerateRSASignature( const uint8_t* message, size_t message_length, uint8_t* signature, size_t* signature_length, RSA_Padding_Scheme padding_scheme) { - if (message == nullptr || message_length == 0 || signature == nullptr || - signature_length == 0) { - LOGE("OEMCrypto_ERROR_INVALID_CONTEXT"); + if (padding_scheme != kSign_PKCS1_Block1) { + LOGE("Only PKCS1 block1 padding scheme allowed"); return OEMCrypto_ERROR_INVALID_CONTEXT; } - if (!rsa_key()) { + if (!rsa_key_) { LOGE("No RSA key set"); return OEMCrypto_ERROR_INVALID_RSA_KEY; } - if (*signature_length < static_cast(RSA_size(rsa_key()))) { - *signature_length = RSA_size(rsa_key()); - return OEMCrypto_ERROR_SHORT_BUFFER; - } - if (((padding_scheme & allowed_schemes_) != padding_scheme) || - (padding_scheme != kSign_PKCS1_Block1)) { - LOGE("padding_scheme not allowed"); - return OEMCrypto_ERROR_INVALID_RSA_KEY; - } - // This is the maximum digest size possible for PKCS1 block type 1, - // as used for a CAST receiver. - const size_t max_digest_size = 83u; - if (message_length > max_digest_size) { - LOGE("RSA digest too large"); - return OEMCrypto_ERROR_SIGNATURE_FAILURE; - } - // Pad the message with PKCS1 padding, and then encrypt. - const int status = RSA_private_encrypt(message_length, message, signature, - rsa_key(), RSA_PKCS1_PADDING); - if (status < 0) { - LOGE("Error in RSA private encrypt. status = %d", status); - dump_boringssl_error(); - return OEMCrypto_ERROR_UNKNOWN_FAILURE; - } - *signature_length = static_cast(RSA_size(rsa_key())); - return OEMCrypto_SUCCESS; + return rsa_key_->GenerateSignature(message, message_length, kRsaPkcs1Cast, + signature, signature_length); } // Validate message signature @@ -1034,24 +933,19 @@ OEMCryptoResult SessionContext::InstallKey( } bool SessionContext::InstallRSAEncryptedKey( - const uint8_t* encrypted_message_key, size_t encrypted_message_key_length) { - encryption_key_.resize(RSA_size(rsa_key())); - const int decrypted_size = RSA_private_decrypt( - encrypted_message_key_length, encrypted_message_key, &encryption_key_[0], - rsa_key(), RSA_PKCS1_OAEP_PADDING); - if (-1 == decrypted_size) { - LOGE("[RSADeriveKeys(): error decrypting session key.]"); - dump_boringssl_error(); + const std::vector& enc_encryption_key) { + if (!rsa_key_) { + LOGE("Session does not have an OEM cert key"); return false; } - encryption_key_.resize(decrypted_size); - if (decrypted_size != static_cast(wvoec::KEY_SIZE)) { - LOGE("[RSADeriveKeys(): error. Session key is wrong size: %d.]", - decrypted_size); - dump_boringssl_error(); - encryption_key_.clear(); + + std::vector encryption_key = + rsa_key_->DecryptEncryptionKey(enc_encryption_key); + if (encryption_key.empty()) { + LOGE("Failed to decrypt session encryption key"); return false; } + encryption_key_ = std::move(encryption_key); return true; } @@ -1162,23 +1056,23 @@ bool SessionContext::EncryptRSAKey(const uint8_t* pkcs8_rsa_key, return true; } -bool SessionContext::LoadRSAKey(const uint8_t* pkcs8_rsa_key, - size_t rsa_key_length) { - rsa_key_.reset(); - if (rsa_key_length < 8) { - LOGE("[LoadRSAKey(): Very Short Buffer]"); +bool SessionContext::LoadRsaDrmKey(const uint8_t* pkcs8_rsa_key, + size_t rsa_key_length) { + std::unique_ptr key = + RsaPrivateKey::Load(pkcs8_rsa_key, rsa_key_length); + if (!key) { + LOGE("Failed to parse RSA key"); return false; } - if ((memcmp(pkcs8_rsa_key, "SIGN", 4) == 0)) { - uint32_t schemes_n; - memcpy((uint8_t*)&schemes_n, pkcs8_rsa_key + 4, sizeof(uint32_t)); - allowed_schemes_ = htonl(schemes_n); - pkcs8_rsa_key += 8; - rsa_key_length -= 8; - } else { - allowed_schemes_ = kSign_RSASSA_PSS; + constexpr uint8_t kAllSchemes = kSign_RSASSA_PSS | kSign_PKCS1_Block1; + if (key->allowed_schemes() == 0 || + (key->allowed_schemes() & kAllSchemes) == kAllSchemes) { + LOGE("RSA DRM key has an invalid set of schemes: allowed_schemes = 0x%08x", + key->allowed_schemes()); + return false; } - return rsa_key_.LoadPkcs8RsaKey(pkcs8_rsa_key, rsa_key_length); + rsa_key_ = std::move(key); + return true; } OEMCryptoResult SessionContext::CheckKeyUse(const std::string& log_string, @@ -1361,7 +1255,6 @@ OEMCryptoResult SessionContext::Generic_Sign(const uint8_t* in_buffer, return OEMCrypto_SUCCESS; } LOGE("[Generic_Sign(): hmac failed"); - dump_boringssl_error(); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } @@ -1402,7 +1295,6 @@ OEMCryptoResult SessionContext::Generic_Verify(const uint8_t* in_buffer, } } LOGE("[Generic_Verify(): HMAC failed"); - dump_boringssl_error(); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h index e6a1d787..fe942ad6 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h @@ -18,7 +18,7 @@ #include "odk_structs.h" #include "oemcrypto_auth_ref.h" #include "oemcrypto_key_ref.h" -#include "oemcrypto_rsa_key_shared.h" +#include "oemcrypto_rsa_key.h" #include "oemcrypto_session_key_table.h" #include "oemcrypto_types.h" #include "oemcrypto_usage_table_ref.h" @@ -59,21 +59,22 @@ class SessionContextKeys { }; class SessionContext { - public: + SessionContext(CryptoEngine* ce, SessionId sid); SessionContext(CryptoEngine* ce, SessionId sid, - const RSA_shared_ptr& rsa_key); + std::shared_ptr&& rsa_key); SessionContext() = delete; virtual ~SessionContext(); - bool isValid() { return valid_; } + bool isValid() const { return valid_; } - virtual bool DeriveKeys(const std::vector& master_key, - const std::vector& mac_context, - const std::vector& enc_context); - virtual bool RSADeriveKeys(const std::vector& enc_session_key, - const std::vector& mac_context, - const std::vector& enc_context); + virtual OEMCryptoResult DeriveKeys(const std::vector& master_key, + const std::vector& mac_context, + const std::vector& enc_context); + virtual OEMCryptoResult RSADeriveKeys( + const std::vector& enc_session_key, + const std::vector& mac_context, + const std::vector& enc_context); virtual OEMCryptoResult PrepAndSignLicenseRequest(uint8_t* message, size_t message_length, size_t* core_message_length, @@ -87,9 +88,7 @@ class SessionContext { virtual OEMCryptoResult PrepAndSignProvisioningRequest( uint8_t* message, size_t message_length, size_t* core_message_length, uint8_t* signature, size_t* signature_length); - // The size of an RSA signature. This is used when signing as a CAST - // receiver. - size_t RSASignatureSize(); + // Restricted to CAST receivers using PKCS1 block padding only. virtual OEMCryptoResult GenerateRSASignature( const uint8_t* message, size_t message_length, uint8_t* signature, size_t* signature_length, RSA_Padding_Scheme padding_scheme); @@ -141,13 +140,12 @@ class SessionContext { const std::vector& key_data_iv, const std::vector& key_control, const std::vector& key_control_iv); - bool InstallRSAEncryptedKey(const uint8_t* encrypted_message_key, - size_t encrypted_message_key_length); + bool InstallRSAEncryptedKey(const std::vector& enc_encryption_key); bool DecryptRSAKey(const uint8_t* enc_rsa_key, size_t enc_rsa_key_length, const uint8_t* wrapped_rsa_key_iv, uint8_t* pkcs8_rsa_key); bool EncryptRSAKey(const uint8_t* pkcs8_rsa_key, size_t enc_rsa_key_length, const uint8_t* enc_rsa_key_iv, uint8_t* enc_rsa_key); - bool LoadRSAKey(const uint8_t* pkcs8_rsa_key, size_t rsa_key_length); + bool LoadRsaDrmKey(const uint8_t* pkcs8_rsa_key, size_t rsa_key_length); virtual OEMCryptoResult LoadRenewal(const uint8_t* message, size_t message_length, size_t core_message_length, @@ -179,7 +177,6 @@ class SessionContext { encryption_key_ = enc_key; } const std::vector& encryption_key() { return encryption_key_; } - uint32_t allowed_schemes() const { return allowed_schemes_; } // Return true if nonce was set. bool set_nonce(uint32_t nonce); @@ -205,9 +202,9 @@ class SessionContext { protected: // Signature size of the currently loaded private key. - size_t CertSignatureSize(); + size_t CertSignatureSize() const; // Signature size when using a keybox or OEM Cert's private key. - size_t ROTSignatureSize(); + size_t ROTSignatureSize() const; virtual OEMCryptoResult GenerateCertSignature(const uint8_t* message, size_t message_length, uint8_t* signature, @@ -257,46 +254,52 @@ class SessionContext { // entry, it also checks the usage entry. OEMCryptoResult CheckKeyUse(const std::string& log_string, uint32_t use_type, OEMCryptoBufferType buffer_type); - RSA* rsa_key() { return rsa_key_.get(); } - bool valid_; - CryptoEngine* ce_; + bool valid_ = false; + CryptoEngine* ce_ = nullptr; SessionId id_; + + // Message keys. + std::shared_ptr rsa_key_; std::vector mac_key_server_; std::vector mac_key_client_; std::vector encryption_key_; std::vector session_key_; - const Key* current_content_key_; - std::unique_ptr session_keys_; + ODK_NonceValues nonce_values_; uint8_t license_request_hash_[ODK_SHA256_HASH_SIZE]; - RSA_shared_ptr rsa_key_; - uint32_t allowed_schemes_; // for RSA signatures. - bool decrypt_started_; // If the license has been used in this session. + + // Content/entitlement keys. + const Key* current_content_key_ = nullptr; + std::unique_ptr session_keys_; + + bool decrypt_started_ = + false; // If the license has been used in this session. ODK_TimerLimits timer_limits_; ODK_ClockValues clock_values_; std::unique_ptr usage_entry_; - SRMVersionStatus srm_requirements_status_; + SRMVersionStatus srm_requirements_status_ = NoSRMVersion; enum UsageEntryStatus { kNoUsageEntry, // No entry loaded for this session. kUsageEntryNew, // After entry was created. kUsageEntryLoaded, // After loading entry or loading keys. }; - UsageEntryStatus usage_entry_status_; + UsageEntryStatus usage_entry_status_ = kNoUsageEntry; // These are used when doing full decrypt path testing. - bool compute_hash_; // True if the current frame needs a hash. - uint32_t current_hash_; // Running CRC hash of frame. - uint32_t given_hash_; // True CRC hash of frame. - uint32_t current_frame_number_; // Current frame for CRC hash. - uint32_t bad_frame_number_; // Frame number with bad hash. - OEMCryptoResult hash_error_; // Error code for first bad frame. + bool compute_hash_ = false; // True if the current frame needs a hash. + uint32_t current_hash_ = 0; // Running CRC hash of frame. + uint32_t given_hash_ = 0; // True CRC hash of frame. + uint32_t current_frame_number_ = 0; // Current frame for CRC hash. + uint32_t bad_frame_number_ = 0; // Frame number with bad hash. + OEMCryptoResult hash_error_ = + OEMCrypto_SUCCESS; // Error code for first bad frame. // The bare minimum state machine is to only call each of these function // categories at most once. - bool state_nonce_created_; - bool state_request_signed_; - bool state_response_loaded_; + bool state_nonce_created_ = false; + bool state_request_signed_ = false; + bool state_response_loaded_ = false; CORE_DISALLOW_COPY_AND_ASSIGN(SessionContext); }; From 9f7e2c4413f150ff30541bbc20c347ea58c40101 Mon Sep 17 00:00:00 2001 From: Alex Dale Date: Thu, 18 Feb 2021 20:00:15 -0800 Subject: [PATCH 2/5] Restructed reference root of trust (3/3 OEM Cert) [ Merge of http://go/wvgerrit/116944 ] This change is the last part of a three part change for restructing the root of trust used by the reference implementation. OEM Certificates are now managed by the root of trust of the crypto engine. Previously, OEM certs where handled separately on a session by session basis. Bug: 135283522 Test: oemcrypto_unittests ce_cdm_tests Change-Id: I6cf1fa3fade28baad85b5fce57a8eab6f2ed17c1 --- .../oemcrypto/ref/src/oemcrypto_auth_ref.cpp | 75 +++++++++++++------ .../oemcrypto/ref/src/oemcrypto_auth_ref.h | 29 +++++-- ...crypto_engine_device_properties_prov30.cpp | 34 +++------ .../oemcrypto/ref/src/oemcrypto_engine_ref.h | 33 +++++--- .../oemcrypto/ref/src/oemcrypto_ref.cpp | 9 +-- .../oemcrypto/ref/src/oemcrypto_session.cpp | 9 +++ .../oemcrypto/ref/src/oemcrypto_session.h | 3 + 7 files changed, 120 insertions(+), 72 deletions(-) diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.cpp index 984de937..b62cd39f 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.cpp @@ -177,9 +177,6 @@ static const uint8_t kTestRSAPKCS8PrivateKeyInfo2_2048[] = { 0x72, 0x2c, 0xf7, 0xc1, 0x22, 0x36, 0xd9, 0x18, 0x56, 0xfe, 0x39, 0x28, 0x33, 0xe0, 0xdb, 0x03 }; - -// Filler for returning vector references. -const std::vector kEmptyVector; } // namespace bool AuthenticationRoot::Initialize(OEMCrypto_ProvisioningMethod method) { @@ -187,10 +184,12 @@ bool AuthenticationRoot::Initialize(OEMCrypto_ProvisioningMethod method) { // If provisioning method is something other than ProvisioningError // indicates it has already been initialized before. Must // existing data. - rsa_key_.reset(); - test_rsa_key_.reset(); + drm_cert_key_.reset(); + test_drm_cert_key_.reset(); keybox_.reset(); test_keybox_.reset(); + oem_cert_.reset(); + oem_cert_key_.reset(); } prov_method_ = method; switch (method) { @@ -198,7 +197,7 @@ bool AuthenticationRoot::Initialize(OEMCrypto_ProvisioningMethod method) { std::unique_ptr key = RsaPrivateKey::Load(kPrivateKey, kPrivateKeySize); if (key) { - rsa_key_ = std::move(key); + drm_cert_key_ = std::move(key); } else { // This error message is OK in unit tests which use test certificate. LOGE( @@ -230,8 +229,7 @@ bool AuthenticationRoot::IsValid() const { return HasDeviceKey(); } case OEMCrypto_OEMCertificate: { - // TODO(sigquit): Add OEM Certificate validation. - return true; + return HasOemCertKey() && HasDeviceKey(); } default: { LOGE("Root of trust is not properly initialized"); @@ -251,8 +249,11 @@ OEMCryptoResult AuthenticationRoot::IsKeyboxOrOemCertValid() const { return kb->IsKeyboxValid(); } case OEMCrypto_OEMCertificate: { - LOGW("OEM certificate validation is not implemented"); - return OEMCrypto_ERROR_NOT_IMPLEMENTED; + if (!oem_cert_) { + LOGW("OEM cert is not installed"); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + return oem_cert_->IsCertificateValid(); } case OEMCrypto_DrmCertificate: { return OEMCrypto_ERROR_NOT_IMPLEMENTED; @@ -300,7 +301,7 @@ std::vector AuthenticationRoot::DeviceId() const { } if (prov_method_ == OEMCrypto_Keybox) { LOGE("Expected keybox to be set for a device ID"); - return kEmptyVector; + return std::vector(); } return std::vector(kFakeDeviceId.begin(), kFakeDeviceId.end()); } @@ -311,7 +312,7 @@ std::vector AuthenticationRoot::DeviceKey() const { return kb->DeviceKey(); } LOGE("No device key has been set"); - return kEmptyVector; + return std::vector(); } bool AuthenticationRoot::HasDeviceKey() const { return keybox() != nullptr; } @@ -326,7 +327,7 @@ OEMCryptoResult AuthenticationRoot::LoadTestRsaKey() { LOGE("System does not support DRM certificates"); return OEMCrypto_ERROR_NOT_IMPLEMENTED; } - if (test_rsa_key_) { + if (test_drm_cert_key_) { LOGE("Test RSA key is already loaded"); return OEMCrypto_ERROR_INSUFFICIENT_RESOURCES; } @@ -337,7 +338,7 @@ OEMCryptoResult AuthenticationRoot::LoadTestRsaKey() { LOGE("Failed to load test RSA key"); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - test_rsa_key_ = std::move(key); + test_drm_cert_key_ = std::move(key); return OEMCrypto_SUCCESS; } @@ -399,22 +400,48 @@ OEMCryptoResult AuthenticationRoot::GetKeyData(uint8_t* key_data, return kb->GetKeyData(key_data, key_data_length); } +OEMCryptoResult AuthenticationRoot::InstallOemCertificate( + const uint8_t* private_key, size_t private_key_size, + const uint8_t* public_cert, size_t public_cert_size) { + if (prov_method_ != OEMCrypto_OEMCertificate) { + LOGE("System does not support OEM certificates"); + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + } + if (oem_cert_ || oem_cert_key_) { + LOGE("OEM certificate is already installed"); + return OEMCrypto_ERROR_INSUFFICIENT_RESOURCES; + } + std::unique_ptr oem_cert = OemCertificate::Create( + private_key, private_key_size, public_cert, public_cert_size); + if (!oem_cert) { + LOGE("Failed to install OEM certificate as root of trust"); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + if (oem_cert->key_type() != OemCertificate::kRsa) { + LOGE("Only RSA-based OEM certificates supported"); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + std::unique_ptr oem_cert_key = + RsaPrivateKey::Load(oem_cert->GetPrivateKey()); + if (!oem_cert_key) { + LOGE("Failed to parse OEM certificate private key"); + return OEMCrypto_ERROR_INVALID_RSA_KEY; + } + oem_cert_ = std::move(oem_cert); + oem_cert_key_ = std::move(oem_cert_key); + return OEMCrypto_SUCCESS; +} + OEMCryptoResult AuthenticationRoot::GetOemPublicCertificate( uint8_t* public_cert, size_t* public_cert_length) const { if (prov_method_ != OEMCrypto_OEMCertificate) { LOGE("System does not support OEM certificates"); return OEMCrypto_ERROR_NOT_IMPLEMENTED; } - LOGE("OEM certificates have not been implemented on auth root"); - return OEMCrypto_ERROR_NOT_IMPLEMENTED; -} - -const std::vector& AuthenticationRoot::GetOemPrivateKey() const { - if (prov_method_ != OEMCrypto_OEMCertificate) { - LOGE("System does not support OEM certificates"); - return kEmptyVector; + if (!oem_cert_) { + LOGE("OEM certificate is not installed"); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - LOGE("OEM certificates have not been implemented on auth root"); - return kEmptyVector; + return oem_cert_->GetPublicCertificate(public_cert, public_cert_length); } } // namespace wvoec_ref diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.h index 9050b983..c1ae01db 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.h @@ -15,6 +15,7 @@ #include "OEMCryptoCENC.h" // Needed for enums only. #include "disallow_copy_and_assign.h" #include "oemcrypto_keybox_ref.h" +#include "oemcrypto_oem_cert.h" #include "oemcrypto_rsa_key.h" namespace wvoec_ref { @@ -67,12 +68,12 @@ class AuthenticationRoot { // Returns the shared RSA private key from the built-in DRM // Certificate. std::shared_ptr ShareDrmCertKey() { - return test_rsa_key_ ? test_rsa_key_ : rsa_key_; + return test_drm_cert_key_ ? test_drm_cert_key_ : drm_cert_key_; } RsaPrivateKey* DrmCertKey() const { - return test_rsa_key_ ? test_rsa_key_.get() : rsa_key_.get(); + return test_drm_cert_key_ ? test_drm_cert_key_.get() : drm_cert_key_.get(); } - bool HasDrmCertKey() const { return test_rsa_key_ || rsa_key_; } + bool HasDrmCertKey() const { return test_drm_cert_key_ || drm_cert_key_; } // Loads the system's built-in RSA key. Only implemented for // devices that are that pre-provisioned with a built-in DRM @@ -82,7 +83,7 @@ class AuthenticationRoot { OEMCryptoResult LoadTestRsaKey(); // Removes any installed test RSA key. - void RemoveTestRsaKey() { test_rsa_key_.reset(); } + void RemoveTestRsaKey() { test_drm_cert_key_.reset(); } // Keybox-based root of trust API. @@ -124,6 +125,14 @@ class AuthenticationRoot { // OEM Certificate-base root of trust API. + // Installs an OEM certificate as the root of trust. The provided + // private key and public cert are parsed, but not validated. The + // private key will be made available for sessions to load. + OEMCryptoResult InstallOemCertificate(const uint8_t* private_key, + size_t private_key_size, + const uint8_t* public_cert, + size_t public_cert_size); + // For OEM Cert-based devices, returns the OEM Public Certificate // component of the OEM Certificate. // This method implements the expected behavior of @@ -135,7 +144,9 @@ class AuthenticationRoot { // the OEM private key into a session. // Should only be called for devices that use OEM Certificates // for provisioning. - const std::vector& GetOemPrivateKey() const; + std::shared_ptr ShareOemCertKey() { return oem_cert_key_; } + RsaPrivateKey* OemCertKey() const { return oem_cert_key_.get(); } + bool HasOemCertKey() const { return static_cast(oem_cert_key_); } private: OEMCrypto_ProvisioningMethod prov_method_ = OEMCrypto_ProvisioningError; @@ -143,13 +154,17 @@ class AuthenticationRoot { // DRM certificate. // If no keybox, this is the private key of the baked-in DRM // Certificate. - std::shared_ptr rsa_key_; - std::shared_ptr test_rsa_key_; + std::shared_ptr drm_cert_key_; + std::shared_ptr test_drm_cert_key_; // Keybox data. std::unique_ptr keybox_; std::unique_ptr test_keybox_; + // OEM certificate. + std::unique_ptr oem_cert_; + std::shared_ptr oem_cert_key_; + CORE_DISALLOW_COPY_AND_ASSIGN(AuthenticationRoot); }; } // namespace wvoec_ref diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp index 3b17bb63..96134b99 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp @@ -24,6 +24,15 @@ class Prov30CryptoEngine : public CryptoEngine { explicit Prov30CryptoEngine(std::unique_ptr&& file_system) : CryptoEngine(std::move(file_system)) {} + bool Initialize() override { + if (!CryptoEngine::Initialize()) { + return false; + } + const OEMCryptoResult result = InstallOemCertificate( + kOEMPrivateKey, kOEMPrivateKeySize, kOEMPublicCert, kOEMPublicCertSize); + return result == OEMCrypto_SUCCESS; + } + bool config_local_display_only() { return true; } // Returns the max HDCP version supported. @@ -47,31 +56,6 @@ class Prov30CryptoEngine : public CryptoEngine { return OEMCrypto_OEMCertificate; } - OEMCryptoResult get_oem_certificate(SessionContext* session, - uint8_t* public_cert, - size_t* public_cert_length) { - if (kOEMPublicCertSize == 0) { - return OEMCrypto_ERROR_NOT_IMPLEMENTED; - } - if (public_cert_length == nullptr) { - return OEMCrypto_ERROR_UNKNOWN_FAILURE; - } - if (*public_cert_length < kOEMPublicCertSize) { - *public_cert_length = kOEMPublicCertSize; - return OEMCrypto_ERROR_SHORT_BUFFER; - } - *public_cert_length = kOEMPublicCertSize; - if (public_cert == nullptr) { - return OEMCrypto_ERROR_SHORT_BUFFER; - } - memcpy(public_cert, kOEMPublicCert, kOEMPublicCertSize); - if (!session->LoadRsaDrmKey(kOEMPrivateKey, kOEMPrivateKeySize)) { - LOGE("Private RSA Key did not load correctly."); - return OEMCrypto_ERROR_INVALID_RSA_KEY; - } - return OEMCrypto_SUCCESS; - } - // Returns "L3" for a software only library. L1 is for hardware protected // keys and data paths. L2 is for hardware protected keys but no data path // protection. diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h index 70613aff..0fddd30f 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h @@ -75,8 +75,8 @@ class CryptoEngine { OEMCryptoResult LoadTestRsaKey() { return root_of_trust_.LoadTestRsaKey(); } - OEMCryptoResult IsKeyboxValid() const { - return root_of_trust_.IsKeyboxValid(); + OEMCryptoResult IsKeyboxOrOemCertValid() const { + return root_of_trust_.IsKeyboxOrOemCertValid(); } std::vector DeviceRootKey() const { @@ -97,6 +97,26 @@ class CryptoEngine { return root_of_trust_.GetKeyData(key_data, key_data_length); } + OEMCryptoResult InstallOemCertificate(const uint8_t* private_key, + size_t private_key_size, + const uint8_t* public_cert, + size_t public_cert_size) { + return root_of_trust_.InstallOemCertificate(private_key, private_key_size, + public_cert, public_cert_size); + } + + OEMCryptoResult GetOemPublicCertificate(uint8_t* public_cert, + size_t* public_cert_length) const { + return root_of_trust_.GetOemPublicCertificate(public_cert, + public_cert_length); + } + + std::shared_ptr ShareOemPrivateKey() { + return root_of_trust_.ShareOemCertKey(); + } + + bool HasOemPrivateKey() const { return root_of_trust_.HasOemCertKey(); } + virtual void Terminate(); virtual SessionId OpenSession(); @@ -155,15 +175,6 @@ class CryptoEngine { return OEMCrypto_Keybox; } - virtual OEMCryptoResult get_oem_certificate(uint8_t* public_cert, - size_t* public_cert_length) { - return OEMCrypto_ERROR_NOT_IMPLEMENTED; - } - - virtual OEMCryptoResult load_oem_private_key(SessionContext* session) { - return OEMCrypto_ERROR_NOT_IMPLEMENTED; - } - // Used for OEMCrypto_IsAntiRollbackHwPresent. virtual bool config_is_anti_rollback_hw_present() { return false; } diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp index 09b78315..0f65f489 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp @@ -762,10 +762,8 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_IsKeyboxOrOEMCertValid(void) { case OEMCrypto_DrmCertificate: return OEMCrypto_SUCCESS; case OEMCrypto_Keybox: - return crypto_engine->IsKeyboxValid(); case OEMCrypto_OEMCertificate: - // TODO(sigquit): verify that the certificate exists and is valid. - return OEMCrypto_SUCCESS; + return crypto_engine->IsKeyboxOrOemCertValid(); default: LOGE("Invalid provisioning method: %d.", crypto_engine->config_provisioning_method()); @@ -797,7 +795,7 @@ OEMCrypto_LoadOEMPrivateKey(OEMCrypto_SESSION session) { LOGE("OEMCrypto_ERROR_INVALID_SESSION"); return OEMCrypto_ERROR_INVALID_SESSION; } - return crypto_engine->load_oem_private_key(session_ctx); + return session_ctx->LoadOemPrivateKey(); } OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetOEMPublicCertificate( @@ -811,7 +809,8 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetOEMPublicCertificate( crypto_engine->config_provisioning_method()); return OEMCrypto_ERROR_NOT_IMPLEMENTED; } - return crypto_engine->get_oem_certificate(public_cert, public_cert_length); + return crypto_engine->GetOemPublicCertificate(public_cert, + public_cert_length); } OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* device_id, diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp index 69e219f6..96f0b8ea 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp @@ -296,6 +296,15 @@ OEMCryptoResult SessionContext::RSADeriveKeys( return DeriveKeys(session_key_, mac_key_context, enc_key_context); } +OEMCryptoResult SessionContext::LoadOemPrivateKey() { + if (!ce_->HasOemPrivateKey()) { + LOGE("No OEM private key"); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + rsa_key_ = ce_->ShareOemPrivateKey(); + return OEMCrypto_SUCCESS; +} + OEMCryptoResult SessionContext::PrepAndSignLicenseRequest( uint8_t* message, size_t message_length, size_t* core_message_length, uint8_t* signature, size_t* signature_length) { diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h index fe942ad6..e01054eb 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h @@ -75,6 +75,9 @@ class SessionContext { const std::vector& enc_session_key, const std::vector& mac_context, const std::vector& enc_context); + + virtual OEMCryptoResult LoadOemPrivateKey(); + virtual OEMCryptoResult PrepAndSignLicenseRequest(uint8_t* message, size_t message_length, size_t* core_message_length, From 7c8d3e287e14e4f437888c330ae4bf9cffd31a8d Mon Sep 17 00:00:00 2001 From: Rahul Frias Date: Wed, 7 Apr 2021 15:38:05 -0700 Subject: [PATCH 3/5] Correction to addition of LOCAL_LICENSE_KINDS to vendor/widevine Remove incorrectly identified license files in http://go/ag/13998816 Bug: 68860345 Bug: 151177513 Bug: 151953481 Test: mm Change-Id: I676a63598c8a7df11a1cef6d8bebcc9940c961dc --- libwvdrmengine/cdm/core/src/Android.bp | 30 ++++++------------------ libwvdrmengine/cdm/core/test/Android.bp | 31 ++++++------------------- 2 files changed, 14 insertions(+), 47 deletions(-) diff --git a/libwvdrmengine/cdm/core/src/Android.bp b/libwvdrmengine/cdm/core/src/Android.bp index d6631060..5b6afc36 100644 --- a/libwvdrmengine/cdm/core/src/Android.bp +++ b/libwvdrmengine/cdm/core/src/Android.bp @@ -2,29 +2,13 @@ // CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE // DEPENDING ON IT IN YOUR PROJECT. *** package { - default_applicable_licenses: [ - "vendor_widevine_libwvdrmengine_cdm_core_src_license", - ], -} - -// Added automatically by a large-scale-change -// -// large-scale-change included anything that looked like it might be a license -// text as a license_text. e.g. LICENSE, NOTICE, COPYING etc. -// -// Please consider removing redundant or irrelevant files from 'license_text:'. -// See: http://go/android-license-faq -license { - name: "vendor_widevine_libwvdrmengine_cdm_core_src_license", - visibility: [":__subpackages__"], - license_kinds: [ - "legacy_by_exception_only", // by exception only - ], - license_text: [ - "license.cpp", - "license_key_status.cpp", - "license_protocol.proto", - ], + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "vendor_widevine_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + // legacy_by_exception_only (by exception only) + default_applicable_licenses: ["vendor_widevine_license"], } cc_library { diff --git a/libwvdrmengine/cdm/core/test/Android.bp b/libwvdrmengine/cdm/core/test/Android.bp index 6c868c08..c170be40 100644 --- a/libwvdrmengine/cdm/core/test/Android.bp +++ b/libwvdrmengine/cdm/core/test/Android.bp @@ -16,30 +16,13 @@ // CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE // DEPENDING ON IT IN YOUR PROJECT. *** package { - default_applicable_licenses: [ - "vendor_widevine_libwvdrmengine_cdm_core_test_license", - ], -} - -// Added automatically by a large-scale-change -// -// large-scale-change included anything that looked like it might be a license -// text as a license_text. e.g. LICENSE, NOTICE, COPYING etc. -// -// Please consider removing redundant or irrelevant files from 'license_text:'. -// See: http://go/android-license-faq -license { - name: "vendor_widevine_libwvdrmengine_cdm_core_test_license", - visibility: [":__subpackages__"], - license_kinds: [ - "legacy_by_exception_only", // by exception only - ], - license_text: [ - "license_keys_unittest.cpp", - "license_request.cpp", - "license_request.h", - "license_unittest.cpp", - ], + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "vendor_widevine_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + // legacy_by_exception_only (by exception only) + default_applicable_licenses: ["vendor_widevine_license"], } filegroup { From a40af9d1efae590900889b059180de0a81ac5a68 Mon Sep 17 00:00:00 2001 From: Rahul Frias Date: Thu, 8 Apr 2021 11:54:06 -0700 Subject: [PATCH 4/5] Reword "blacklisted" to "forbidden" [ Merge of http://go/wvgerrit/113563 ] Bug: 159847851 Test: WV unit/integration tests Change-Id: I138b3e3291cb9e75841d092ca1bfa9a652ad9f9a --- libwvdrmengine/cdm/test/cdm_feature_test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libwvdrmengine/cdm/test/cdm_feature_test.sh b/libwvdrmengine/cdm/test/cdm_feature_test.sh index bec93214..c4503550 100644 --- a/libwvdrmengine/cdm/test/cdm_feature_test.sh +++ b/libwvdrmengine/cdm/test/cdm_feature_test.sh @@ -76,11 +76,11 @@ write_options_txt_file() echo "srm_load_version -1" >> $HOST_OPTIONS_PATH if [ "$srm_revoked" == "$YES" ]; then - echo "srm_blacklisted_device_attached 1" >> $HOST_OPTIONS_PATH + echo "srm_forbidden_device_attached 1" >> $HOST_OPTIONS_PATH echo "srm_attached_device_id 20362845044" >> $HOST_OPTIONS_PATH # echo "srm_attached_device_id 1079148782731" >> $HOST_OPTIONS_PATH else - echo "srm_blacklisted_device_attached 0" >> $HOST_OPTIONS_PATH + echo "srm_forbidden_device_attached 0" >> $HOST_OPTIONS_PATH echo "srm_attached_device_id 12345678" >> $HOST_OPTIONS_PATH fi From ccda4faf7b869d271b218d5297d7898fa4cf0af5 Mon Sep 17 00:00:00 2001 From: Alex Dale Date: Fri, 9 Apr 2021 00:43:34 -0700 Subject: [PATCH 5/5] Cleaned up OEMCrypto security level getter. [ Merge of http://go/wvgerrit/121566 ] This clean up is part of a larger usage table initialization fix. Bug: 169195093 Change-Id: I3ee818d1e5621f1f2fa64b189da4e66503d5e680 --- .../cdm/core/src/crypto_session.cpp | 61 +++++++++++-------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index e8b9a23a..241424d9 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -490,37 +490,46 @@ CdmSecurityLevel CryptoSession::GetSecurityLevel() { } CdmSecurityLevel CryptoSession::GetSecurityLevel( - SecurityLevel requested_level) { - LOGV("Getting security level: requested_level = %d", - static_cast(requested_level)); + SecurityLevel requested_security_level) { + LOGV("Getting security level: requested_security_level = %d", + static_cast(requested_security_level)); RETURN_IF_UNINITIALIZED(kSecurityLevelUninitialized); - - std::string security_level; - WithOecReadLock("GetSecurityLevel", [&] { - security_level = OEMCrypto_SecurityLevel(requested_level); + const char* const level = WithOecReadLock("GetSecurityLevel", [&] { + return OEMCrypto_SecurityLevel(requested_security_level); }); - - if ((security_level.size() != 2) || (security_level.at(0) != 'L')) { + if (level == nullptr) { + LOGE("Security level is null: requested_security_level = %d", + static_cast(requested_security_level)); return kSecurityLevelUnknown; } - - CdmSecurityLevel cdm_security_level; - switch (security_level.at(1)) { - case '1': - cdm_security_level = kSecurityLevelL1; - break; - case '2': - cdm_security_level = kSecurityLevelL2; - break; - case '3': - cdm_security_level = kSecurityLevelL3; - break; - default: - cdm_security_level = kSecurityLevelUnknown; - break; + // Check length in the event of a bad pointer. + // |kMaxSecurityLevelLength| is a value larger than expected to + // be able to detect an overrun. + constexpr size_t kMaxSecurityLevelLength = 5; + const size_t length = strnlen(level, kMaxSecurityLevelLength); + constexpr size_t kExpectedSecurityLevelLength = 2; + if (length != kExpectedSecurityLevelLength) { + LOGE( + "Unexpected security level length: " + "length = %zu, requested_security_level = %d", + length, static_cast(requested_security_level)); + return kSecurityLevelUnknown; } - - return cdm_security_level; + const std::string security_level(level); + if (security_level == "L1") { + return kSecurityLevelL1; + } + if (security_level == "L2") { + return kSecurityLevelL2; + } + if (security_level == "L3") { + return kSecurityLevelL3; + } + LOGE( + "Ill-formed security level: " + "level = \"%s\", requested_security_level = %d", + security_level.c_str(), static_cast(requested_security_level)); + return kSecurityLevelUnknown; } CdmResponseType CryptoSession::GetInternalDeviceUniqueId(