diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 0563e4e9..dee93007 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -1201,7 +1201,7 @@ CdmResponseType CryptoSession::LoadEntitledContentKeys( CdmResponseType CryptoSession::LoadCertificatePrivateKey( const std::string& wrapped_key) { // TODO(b/141655126): Getting the OEM Cert no longer loads the private key. - // Call OEMCrypto_GetOEMPublicCertificate before OEMCrypto_LoadDeviceRSAKey + // Call OEMCrypto_GetOEMPublicCertificate before OEMCrypto_LoadDRMPrivateKey // 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(); @@ -1216,10 +1216,11 @@ CdmResponseType CryptoSession::LoadCertificatePrivateKey( metrics_->oemcrypto_get_oem_public_certificate_.Increment(sts); LOGV("Loading device RSA key: id = %u", oec_session_id_); + // TODO(b/140813486): determine if cert is RSA or ECC. WithOecSessionLock( - "LoadCertificatePrivateKey() calling OEMCrypto_LoadDeviceRSAKey()", [&] { - M_TIME(sts = OEMCrypto_LoadDeviceRSAKey( - oec_session_id_, + "LoadCertificatePrivateKey() calling OEMCrypto_LoadDRMPrivateKey()", [&] { + M_TIME(sts = OEMCrypto_LoadDRMPrivateKey( + oec_session_id_, OEMCrypto_RSA_Private_Key, reinterpret_cast(wrapped_key.data()), wrapped_key.size()), metrics_, oemcrypto_load_device_rsa_key_, sts); diff --git a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp index e35c163d..280ac36d 100644 --- a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp +++ b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp @@ -200,6 +200,9 @@ typedef OEMCryptoResult (*L1_RewrapDeviceRSAKey_t)( typedef OEMCryptoResult (*L1_LoadDeviceRSAKey_t)(OEMCrypto_SESSION session, const uint8_t* wrapped_rsa_key, size_t wrapped_rsa_key_length); +typedef OEMCryptoResult (*L1_LoadDRMPrivateKey_t)( + OEMCrypto_SESSION session, OEMCrypto_PrivateKeyType key_type, + const uint8_t* wrapped_rsa_key, size_t wrapped_rsa_key_length); typedef OEMCryptoResult (*L1_LoadTestRSAKey_t)(); typedef OEMCryptoResult (*L1_GenerateRSASignature_t)( OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, @@ -351,6 +354,7 @@ struct FunctionPointers { L1_GetRandom_t GetRandom; L1_RewrapDeviceRSAKey_t RewrapDeviceRSAKey; L1_LoadDeviceRSAKey_t LoadDeviceRSAKey; + L1_LoadDRMPrivateKey_t LoadDRMPrivateKey; L1_LoadTestRSAKey_t LoadTestRSAKey; L1_GenerateRSASignature_t GenerateRSASignature; L1_DeriveKeysFromSessionKey_t DeriveKeysFromSessionKey; @@ -827,7 +831,8 @@ class Adapter { LOOKUP_ALL(10, IsAntiRollbackHwPresent, OEMCrypto_IsAntiRollbackHwPresent); LOOKUP_ALL( 8, IsKeyboxOrOEMCertValid, OEMCrypto_IsKeyboxOrOEMCertValid); LOOKUP_ALL(13, IsSRMUpdateSupported, OEMCrypto_IsSRMUpdateSupported); - LOOKUP_ALL( 8, LoadDeviceRSAKey, OEMCrypto_LoadDeviceRSAKey); + LOOKUP( 8, 15, LoadDeviceRSAKey, OEMCrypto_LoadDeviceRSAKey); + LOOKUP_ALL(16, LoadDRMPrivateKey, OEMCrypto_LoadDRMPrivateKey); LOOKUP( 8, 8, LoadKeys_V8, OEMCrypto_LoadKeys_V8); LOOKUP( 9, 10, LoadKeys_V9_or_V10, OEMCrypto_LoadKeys_V9_or_V10); LOOKUP(11, 12, LoadKeys_V11_or_V12, OEMCrypto_LoadKeys_V11_or_V12); @@ -980,6 +985,8 @@ class Adapter { level3_.GetRandom = Level3_GetRandom; level3_.RewrapDeviceRSAKey = Level3_RewrapDeviceRSAKey; level3_.LoadDeviceRSAKey = Level3_LoadDeviceRSAKey; + // TODO(b/139814713): implement V16 DecryptCENC for Haystack L3 + // level3_.LoadDRMPrivateKey = Level3_LoadDRMPrivateKey; level3_.LoadTestRSAKey = Level3_LoadTestRSAKey; level3_.GenerateRSASignature = Level3_GenerateRSASignature; level3_.DeriveKeysFromSessionKey = Level3_DeriveKeysFromSessionKey; @@ -2263,12 +2270,22 @@ extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey( wrapped_rsa_key_length); } -extern "C" OEMCryptoResult OEMCrypto_LoadDeviceRSAKey( - OEMCrypto_SESSION session, const uint8_t* wrapped_rsa_key, - size_t wrapped_rsa_key_length) { +extern "C" OEMCryptoResult OEMCrypto_LoadDRMPrivateKey( + OEMCrypto_SESSION session, OEMCrypto_PrivateKeyType key_type, + const uint8_t* wrapped_rsa_key, size_t wrapped_rsa_key_length) { if (!gAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; LevelSession pair = gAdapter->GetSession(session); if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; + // TODO(152701491): re-introduce version checking. LoadDRMPrivateKey should + // always be present for v16 device. + if (pair.fcn->LoadDRMPrivateKey != nullptr) { + return pair.fcn->LoadDRMPrivateKey(pair.session, key_type, wrapped_rsa_key, + wrapped_rsa_key_length); + } + if (key_type != OEMCrypto_RSA_Private_Key) { + LOGE("ECC not supported"); + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + } if (pair.fcn->LoadDeviceRSAKey == nullptr) return OEMCrypto_ERROR_NOT_IMPLEMENTED; return pair.fcn->LoadDeviceRSAKey(pair.session, wrapped_rsa_key, diff --git a/libwvdrmengine/mediadrm/include/WVGenericCryptoInterface.h b/libwvdrmengine/mediadrm/include/WVGenericCryptoInterface.h index f6b8bcfd..96cb0541 100644 --- a/libwvdrmengine/mediadrm/include/WVGenericCryptoInterface.h +++ b/libwvdrmengine/mediadrm/include/WVGenericCryptoInterface.h @@ -73,8 +73,8 @@ class WVGenericCryptoInterface { virtual OEMCryptoResult loadDeviceRSAKey(OEMCrypto_SESSION session, const uint8_t* wrapped_rsa_key, size_t wrapped_rsa_key_length) { - return OEMCrypto_LoadDeviceRSAKey(session, wrapped_rsa_key, - wrapped_rsa_key_length); + return OEMCrypto_LoadDRMPrivateKey(session, OEMCrypto_RSA_Private_Key, + wrapped_rsa_key, wrapped_rsa_key_length); } virtual OEMCryptoResult generateRSASignature( diff --git a/libwvdrmengine/mediadrm/include_hidl/WVGenericCryptoInterface.h b/libwvdrmengine/mediadrm/include_hidl/WVGenericCryptoInterface.h index f0ddacf6..907755c2 100644 --- a/libwvdrmengine/mediadrm/include_hidl/WVGenericCryptoInterface.h +++ b/libwvdrmengine/mediadrm/include_hidl/WVGenericCryptoInterface.h @@ -73,8 +73,8 @@ class WVGenericCryptoInterface { virtual OEMCryptoResult loadDeviceRSAKey(OEMCrypto_SESSION session, const uint8_t* wrapped_rsa_key, size_t wrapped_rsa_key_length) { - return OEMCrypto_LoadDeviceRSAKey(session, wrapped_rsa_key, - wrapped_rsa_key_length); + return OEMCrypto_LoadDRMPrivateKey(session, OEMCrypto_RSA_Private_Key, + wrapped_rsa_key, wrapped_rsa_key_length); } virtual OEMCryptoResult generateRSASignature( diff --git a/libwvdrmengine/mediadrm/src/WVGenericCryptoInterface.cpp b/libwvdrmengine/mediadrm/src/WVGenericCryptoInterface.cpp index ba9d9a0b..ac441088 100644 --- a/libwvdrmengine/mediadrm/src/WVGenericCryptoInterface.cpp +++ b/libwvdrmengine/mediadrm/src/WVGenericCryptoInterface.cpp @@ -27,8 +27,8 @@ OEMCryptoResult WVGenericCryptoInterface::signRSA(const uint8_t* wrapped_rsa_key OEMCrypto_SESSION session; OEMCryptoResult sts = OEMCrypto_OpenSession(&session); if (sts != OEMCrypto_SUCCESS) return sts; - sts = OEMCrypto_LoadDeviceRSAKey(session, wrapped_rsa_key, - wrapped_rsa_key_length); + sts = OEMCrypto_LoadDRMPrivateKey(session, OEMCrypto_RSA_Private_Key, + wrapped_rsa_key, wrapped_rsa_key_length); if (sts == OEMCrypto_SUCCESS) { size_t signatureSize = 0; sts = OEMCrypto_GenerateRSASignature(session, message, message_length, diff --git a/libwvdrmengine/mediadrm/src_hidl/WVGenericCryptoInterface.cpp b/libwvdrmengine/mediadrm/src_hidl/WVGenericCryptoInterface.cpp index 505fd38e..afba938f 100644 --- a/libwvdrmengine/mediadrm/src_hidl/WVGenericCryptoInterface.cpp +++ b/libwvdrmengine/mediadrm/src_hidl/WVGenericCryptoInterface.cpp @@ -26,8 +26,8 @@ OEMCryptoResult WVGenericCryptoInterface::signRSA(const uint8_t* wrapped_rsa_key OEMCrypto_SESSION session; OEMCryptoResult sts = OEMCrypto_OpenSession(&session); if (sts != OEMCrypto_SUCCESS) return sts; - sts = OEMCrypto_LoadDeviceRSAKey(session, wrapped_rsa_key, - wrapped_rsa_key_length); + sts = OEMCrypto_LoadDRMPrivateKey(session, OEMCrypto_RSA_Private_Key, + wrapped_rsa_key, wrapped_rsa_key_length); if (sts == OEMCrypto_SUCCESS) { size_t signatureSize = 0; sts = OEMCrypto_GenerateRSASignature(session, message, message_length, diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp index cfede60b..11276516 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp @@ -890,7 +890,7 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( // For the reference implementation, the wrapped key and the encrypted // key are the same size -- just encrypted with different keys. // We add 32 bytes for a context, 32 for iv, and 32 bytes for a signature. - // Important: This layout must match OEMCrypto_LoadDeviceRSAKey below. + // Important: This layout must match OEMCrypto_LoadDRMPrivateKey below. const size_t buffer_size = enc_rsa_key_length + sizeof(WrappedRSAKey); if (wrapped_rsa_key == nullptr || *wrapped_rsa_key_length < buffer_size) { @@ -1007,7 +1007,7 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey( // For the reference implementation, the wrapped key and the encrypted // key are the same size -- just encrypted with different keys. // We add 32 bytes for a context, 32 for iv, and 32 bytes for a signature. - // Important: This layout must match OEMCrypto_LoadDeviceRSAKey below. + // Important: This layout must match OEMCrypto_LoadDRMPrivateKey below. const size_t buffer_size = enc_rsa_key_length + sizeof(WrappedRSAKey); if (wrapped_rsa_key == nullptr || *wrapped_rsa_key_length < buffer_size) { @@ -1134,7 +1134,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadProvisioning( // For the reference implementation, the wrapped key and the encrypted // key are the same size -- just encrypted with different keys. // We add 32 bytes for a context, 32 for iv, and 32 bytes for a signature. - // Important: This layout must match OEMCrypto_LoadDeviceRSAKey below. + // Important: This layout must match OEMCrypto_LoadDRMPrivateKey below. const size_t buffer_size = parsed_response.enc_private_key.length + sizeof(WrappedRSAKey); @@ -1170,24 +1170,28 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadProvisioning( } } -OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadDeviceRSAKey( - OEMCrypto_SESSION session, const uint8_t* wrapped_rsa_key, - size_t wrapped_rsa_key_length) { +OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadDRMPrivateKey( + OEMCrypto_SESSION session, OEMCrypto_PrivateKeyType key_type, + const uint8_t* wrapped_rsa_key, size_t wrapped_rsa_key_length) { if (wrapped_rsa_key == nullptr) { - LOGE("[OEMCrypto_LoadDeviceRSAKey(): OEMCrypto_ERROR_INVALID_CONTEXT]"); + LOGE("OEMCrypto_ERROR_INVALID_CONTEXT nullptr"); return OEMCrypto_ERROR_INVALID_CONTEXT; } if (crypto_engine == nullptr) { - LOGE("OEMCrypto_LoadDeviceRSAKey: OEMCrypto Not Initialized."); + LOGE("OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } + if (key_type != OEMCrypto_RSA_Private_Key) { + LOGE("ECC keys not yet supported in reference code."); + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + } if (crypto_engine->config_provisioning_method() == OEMCrypto_DrmCertificate) { // If we are using a baked in cert, the "wrapped RSA key" should actually be // the magic value for baked-in certificates. if (wrapped_rsa_key_length != sizeof(kBakedInCertificateMagicBytes) || memcmp(kBakedInCertificateMagicBytes, wrapped_rsa_key, wrapped_rsa_key_length) != 0) { - LOGE("OEMCrypto_LoadDeviceRSAKey: Baked in Cert has wrong size."); + LOGE("Baked in Cert has wrong size."); return OEMCrypto_ERROR_INVALID_RSA_KEY; } else { return OEMCrypto_SUCCESS; @@ -1196,13 +1200,13 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadDeviceRSAKey( const WrappedRSAKey* wrapped = reinterpret_cast(wrapped_rsa_key); if (!crypto_engine->ValidRootOfTrust()) { - LOGE("[OEMCrypto_LoadDeviceRSAKey(): ERROR_KEYBOX_INVALID]"); + LOGE("ERROR_KEYBOX_INVALID"); return OEMCrypto_ERROR_KEYBOX_INVALID; } SessionContext* session_ctx = crypto_engine->FindSession(session); if (session_ctx == nullptr || !session_ctx->isValid()) { - LOGE("[OEMCrypto_LoadDeviceRSAKey(): ERROR_INVALID_SESSION]"); + LOGE("ERROR_INVALID_SESSION"); return OEMCrypto_ERROR_INVALID_SESSION; } const std::vector context( @@ -1216,7 +1220,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadDeviceRSAKey( if (!session_ctx->ValidateMessage( wrapped->context, wrapped_rsa_key_length - sizeof(wrapped->signature), wrapped->signature, sizeof(wrapped->signature))) { - LOGE("[LoadDeviceRSAKey(): Could not verify signature]"); + LOGE("Could not verify signature"); return OEMCrypto_ERROR_SIGNATURE_FAILURE; } // Decrypt RSA key. diff --git a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp index 3eab9b53..662063f3 100644 --- a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp +++ b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp @@ -1356,8 +1356,9 @@ bool Session::GenerateRSASessionKey(vector* session_key, void Session::InstallRSASessionTestKey(const vector& wrapped_rsa_key) { ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_LoadDeviceRSAKey(session_id(), wrapped_rsa_key.data(), - wrapped_rsa_key.size())); + OEMCrypto_LoadDRMPrivateKey(session_id(), OEMCrypto_RSA_Private_Key, + wrapped_rsa_key.data(), + wrapped_rsa_key.size())); } void Session::CreateNewUsageEntry(OEMCryptoResult* status) { diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp index df8106cf..06144d70 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp @@ -2874,8 +2874,9 @@ TEST_F(OEMCryptoLoadsCertificate, LoadWrappedRSAKey) { CreateWrappedRSAKey(); Session s; ASSERT_NO_FATAL_FAILURE(s.open()); - sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), wrapped_rsa_key_.data(), - wrapped_rsa_key_.size()); + sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key, + wrapped_rsa_key_.data(), + wrapped_rsa_key_.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); } @@ -2931,8 +2932,9 @@ TEST_F(OEMCryptoLoadsCertificate, TestMultipleRSAKeys) { ASSERT_NO_FATAL_FAILURE( s1.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_LoadDeviceRSAKey(s1.session_id(), wrapped_rsa_key_.data(), - wrapped_rsa_key_.size())); + OEMCrypto_LoadDRMPrivateKey( + s1.session_id(), OEMCrypto_RSA_Private_Key, + wrapped_rsa_key_.data(), wrapped_rsa_key_.size())); Session s2; // Session s2 uses a different rsa key. encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeyInfo4_2048, @@ -3015,8 +3017,9 @@ TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) { while (clock.now() - start_time < kTestDuration) { Session s; ASSERT_NO_FATAL_FAILURE(s.open()); - sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), wrapped_rsa_key_.data(), - wrapped_rsa_key_.size()); + sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key, + wrapped_rsa_key_.data(), + wrapped_rsa_key_.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); const size_t size = 50; vector licenseRequest(size); @@ -3042,8 +3045,9 @@ TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) { Session s; ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_LoadDeviceRSAKey(s.session_id(), wrapped_rsa_key_.data(), - wrapped_rsa_key_.size())); + OEMCrypto_LoadDRMPrivateKey( + s.session_id(), OEMCrypto_RSA_Private_Key, + wrapped_rsa_key_.data(), wrapped_rsa_key_.size())); vector session_key; vector enc_session_key; ASSERT_NO_FATAL_FAILURE( @@ -3119,8 +3123,9 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate { OEMCryptoResult sts; Session s; ASSERT_NO_FATAL_FAILURE(s.open()); - sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), wrapped_rsa_key_.data(), - wrapped_rsa_key_.size()); + sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key, + wrapped_rsa_key_.data(), + wrapped_rsa_key_.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); // Sign a Message @@ -3151,8 +3156,9 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate { OEMCryptoResult sts; Session s; ASSERT_NO_FATAL_FAILURE(s.open()); - sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), wrapped_rsa_key_.data(), - wrapped_rsa_key_.size()); + sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key, + wrapped_rsa_key_.data(), + wrapped_rsa_key_.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); vector licenseRequest(size); @@ -3183,8 +3189,9 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate { OEMCryptoResult sts; Session s; ASSERT_NO_FATAL_FAILURE(s.open()); - sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), wrapped_rsa_key_.data(), - wrapped_rsa_key_.size()); + sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key, + wrapped_rsa_key_.data(), + wrapped_rsa_key_.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); s.GenerateNonce(); vector session_key; @@ -3418,8 +3425,9 @@ class OEMCryptoCastReceiverTest : public OEMCryptoLoadsCertificateAlternates { OEMCryptoResult sts; Session s; ASSERT_NO_FATAL_FAILURE(s.open()); - sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), wrapped_rsa_key_.data(), - wrapped_rsa_key_.size()); + sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key, + wrapped_rsa_key_.data(), + wrapped_rsa_key_.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); // The application will compute the SHA-1 Hash of the message, so this