From 1fd5a8bf371bfb07995fbff2004ef4b9a901d6cb Mon Sep 17 00:00:00 2001 From: Cong Lin Date: Thu, 15 Feb 2024 15:18:21 -0800 Subject: [PATCH 1/8] Add BCC extract tool for BCC uploading test Extract BCC and build info from oemcrypto, construct BCC uploading record and dumps it out a JSON file. The BCC uploader will pick up the output file later. Bug: 312787974 Change-Id: Ie8ef6a75408e8ef8355b1c0de14532de0ae83732 --- .../oemcrypto/test/extract_bcc_tool.cpp | 173 ++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 libwvdrmengine/oemcrypto/test/extract_bcc_tool.cpp diff --git a/libwvdrmengine/oemcrypto/test/extract_bcc_tool.cpp b/libwvdrmengine/oemcrypto/test/extract_bcc_tool.cpp new file mode 100644 index 00000000..a469ea6a --- /dev/null +++ b/libwvdrmengine/oemcrypto/test/extract_bcc_tool.cpp @@ -0,0 +1,173 @@ +// Copyright 2024 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. +// This tool extracts BCC by calling OEMCrypto APIs and generates a CSR file in +// JSON format, which can be handled by CE CDM wv_upload_tool.py. +#include +#include +#include +#include +#include +#include + +#include "OEMCryptoCENC.h" +#include "string_conversions.h" + +namespace { +// Make and Model for system ID resolution. +const std::string kDeviceMake = "widevine_test"; +const std::string kDeviceModel = "prov4"; + +// Informative fields. +const std::string kDeviceArchitecture = "x86_64"; +const std::string kDeviceName = "prov40 test client"; +const std::string kDeviceProduct = "prov40 test"; +const std::string kDeviceBuildInfo = "prov40 test build"; + +// == Utils == + +std::string StringMapToJson( + const std::map& string_map) { + std::string json = "{"; + for (const auto& value_pair : string_map) { + std::string escaped_value = + std::regex_replace(value_pair.second, std::regex("\""), "\\\""); + json.append("\"" + value_pair.first + "\": " + "\"" + escaped_value + + "\","); + } + json.resize(json.size() - 1); // Remove the last comma. + json.append("}"); + return json; +} + +// == Primary == + +bool GetBccAndBuildInfo(std::vector* bcc, + std::string* oemcrypto_build_info) { + // Step 1: Initialize. + OEMCryptoResult result = OEMCrypto_Initialize(); + if (result != OEMCrypto_SUCCESS) { + std::cerr << "Failed to initialize: result = " << result << std::endl; + return false; + } + + // Step 2: Get BCC. + const OEMCrypto_ProvisioningMethod method = OEMCrypto_GetProvisioningMethod(); + if (method != OEMCrypto_BootCertificateChain) { + std::cerr << "ProvisioningMethod is not BCC type: method = "; + std::cerr << method << std::endl; + OEMCrypto_Terminate(); + return false; + } + + bcc->resize(0); + size_t bcc_size = 0; + std::vector additional_signature; // It should be empty. + size_t additional_signature_size = 0; + result = OEMCrypto_GetBootCertificateChain(bcc->data(), &bcc_size, + additional_signature.data(), + &additional_signature_size); + if (additional_signature_size != 0) { + std::cerr << "The additional_signature_size required by OEMCrypto is " + << additional_signature_size + << ", while it is expected to be zero." << std::endl; + OEMCrypto_Terminate(); + return false; + } + if (result == OEMCrypto_ERROR_SHORT_BUFFER) { + bcc->resize(bcc_size); + additional_signature.resize(additional_signature_size); + result = OEMCrypto_GetBootCertificateChain(bcc->data(), &bcc_size, + additional_signature.data(), + &additional_signature_size); + } + if (result != OEMCrypto_SUCCESS) { + std::cerr << "Failed to get BCC: result = " << result << std::endl; + OEMCrypto_Terminate(); + return false; + } + bcc->resize(bcc_size); + + // Step 3: Get oemcrypto build info. + oemcrypto_build_info->resize(0); + size_t oemcrypto_build_info_size = 0; + result = OEMCrypto_BuildInformation(oemcrypto_build_info->data(), + &oemcrypto_build_info_size); + if (result == OEMCrypto_ERROR_SHORT_BUFFER) { + oemcrypto_build_info->resize(oemcrypto_build_info_size); + result = OEMCrypto_BuildInformation(oemcrypto_build_info->data(), + &oemcrypto_build_info_size); + } + if (result != OEMCrypto_SUCCESS) { + std::cerr << "Failed to get build information: result = " << result + << std::endl; + OEMCrypto_Terminate(); + return false; + } + oemcrypto_build_info->resize(oemcrypto_build_info_size); + + // Step 4: Cleanup. + result = OEMCrypto_Terminate(); + if (result != OEMCrypto_SUCCESS) { + std::cerr << "Failed to terminate: result = " << result << std::endl; + return false; + } + return true; +} + +bool GenerateBccRecord(const std::vector& bcc, + const std::string& oemcrypto_build_info, + std::string* bcc_record) { + std::map record; + record["company"] = kDeviceMake; + record["model"] = kDeviceModel; + + record["architecture"] = kDeviceArchitecture; + record["name"] = kDeviceName; + record["product"] = kDeviceProduct; + record["build_info"] = kDeviceBuildInfo; + record["bcc"] = wvutil::Base64Encode(bcc); + record["oemcrypto_build_info"] = oemcrypto_build_info; + + const std::string record_json = StringMapToJson(record); + bcc_record->assign(record_json.begin(), record_json.end()); + return true; +} + +bool OutputBccRecord(const std::string& path, const std::string& record) { + std::cout << "Writing BCC record to file " << path << std::endl; + std::cout << record << std::endl; + std::ofstream out(path); + if (out) out << record; + if (out.bad()) { + std::cerr << "Failed to write BCC record to file " << path << std::endl; + return false; + } + return true; +} +} // namespace + +int main(int argc, char** argv) { + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " " << std::endl; + return 1; + } + const std::string bcc_path = argv[1]; + + std::vector bcc; + std::string oemcrypto_build_info; + if (!GetBccAndBuildInfo(&bcc, &oemcrypto_build_info)) { + std::cerr << "Failed to get BCC or OEMCrypto build info" << std::endl; + return 1; + } + std::string bcc_record; + if (!GenerateBccRecord(bcc, oemcrypto_build_info, &bcc_record)) { + std::cerr << "Failed to generate BCC record" << std::endl; + return 1; + } + if (!OutputBccRecord(bcc_path, bcc_record)) { + std::cerr << "Failed to output BCC record" << std::endl; + return 1; + } + return 0; +} From 202350959d2bc4a3e15bc28aa82d5f0aca4cb3c3 Mon Sep 17 00:00:00 2001 From: Fred Gylys-Colwell Date: Thu, 21 Mar 2024 10:44:38 -0700 Subject: [PATCH 2/8] Quit test setup when test is skipped The SetUp for child classes do not automatically quit when the parent SetUp is skipped. Bug: 305093063 Change-Id: I606a949ef0e94fa87a97268856b7f2d8b9135ebe --- libwvdrmengine/cdm/core/test/duration_use_case_test.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libwvdrmengine/cdm/core/test/duration_use_case_test.cpp b/libwvdrmengine/cdm/core/test/duration_use_case_test.cpp index 7346e510..da6d2765 100644 --- a/libwvdrmengine/cdm/core/test/duration_use_case_test.cpp +++ b/libwvdrmengine/cdm/core/test/duration_use_case_test.cpp @@ -1048,6 +1048,7 @@ class CdmUseCase_LicenseWithRenewal : public RenewalTest { void SetUp() override { RenewalTest::SetUp(); + if(Test::IsSkipped()) return; const uint64_t next_renewal = start_of_playback_ + initial_policy_.renewal_delay; // Allow playback within the initial renewal window. @@ -1253,6 +1254,7 @@ class CdmUseCase_LicenseWithRenewalPlayback : public RenewalTest { void SetUp() override { RenewalTest::SetUp(); + if(Test::IsSkipped()) return; uint64_t next_renewal = start_of_playback_ + initial_policy_.renewal_delay; // Allow playback within the initial renewal window. SleepUntil(start_of_playback_); @@ -1570,6 +1572,7 @@ class CdmUseCase_RenewOnLicenseLoad : public RenewalTest { void SetUp() override { RenewalTest::SetUp(); + if(Test::IsSkipped()) return; // The Renew on License Load feature is only supported on v18+ servers. if (config_.ServerOlderThan(18) || wvoec::global_features.api_version < 18) { @@ -1717,6 +1720,7 @@ class CdmUseCase_Heartbeat : public RenewalTest { void SetUp() override { RenewalTest::SetUp(); + if(Test::IsSkipped()) return; const uint64_t next_renewal = start_of_playback_ + initial_policy_.renewal_delay; // Allow playback within the initial renewal window. From 53d0f5cd6a9f03e646b90f1382f7b6fbad480f49 Mon Sep 17 00:00:00 2001 From: John Bruce Date: Fri, 22 Mar 2024 12:23:04 -0700 Subject: [PATCH 3/8] Label unused parameters in ODK This is necessary so we can remove `-Wno-unused-parameter` in the CDM and OPK builds. PiperOrigin-RevId: 618255022 Merged from https://widevine-internal-review.googlesource.com/194110 Change-Id: I67b9b8cd27422c4b62d361d627fd1c05ed0cbdef --- libwvdrmengine/oemcrypto/odk/include/odk_structs.h | 2 +- libwvdrmengine/oemcrypto/odk/src/core_message_serialize.cpp | 2 ++ libwvdrmengine/oemcrypto/odk/src/odk.c | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libwvdrmengine/oemcrypto/odk/include/odk_structs.h b/libwvdrmengine/oemcrypto/odk/include/odk_structs.h index c0989277..5f93e356 100644 --- a/libwvdrmengine/oemcrypto/odk/include/odk_structs.h +++ b/libwvdrmengine/oemcrypto/odk/include/odk_structs.h @@ -19,7 +19,7 @@ extern "C" { #define ODK_MINOR_VERSION 0 /* ODK Version string. Date changed automatically on each release. */ -#define ODK_RELEASE_DATE "ODK v19.0 2024-02-23" +#define ODK_RELEASE_DATE "ODK v19.0 2024-03-22" /* The lowest version number for an ODK message. */ #define ODK_FIRST_VERSION 16 diff --git a/libwvdrmengine/oemcrypto/odk/src/core_message_serialize.cpp b/libwvdrmengine/oemcrypto/odk/src/core_message_serialize.cpp index b2fc97bf..888b957a 100644 --- a/libwvdrmengine/oemcrypto/odk/src/core_message_serialize.cpp +++ b/libwvdrmengine/oemcrypto/odk/src/core_message_serialize.cpp @@ -143,6 +143,8 @@ bool CreateCoreReleaseResponse(const CoreMessageFeatures& features, int64_t seconds_since_license_requested, int64_t seconds_since_first_decrypt, std::string* oemcrypto_core_message) { + (void)seconds_since_license_requested; + (void)seconds_since_first_decrypt; ODK_ReleaseResponse release_response{}; if (!CreateResponseHeader(features, ODK_Release_Response_Type, &release_response.core_message, core_request)) { diff --git a/libwvdrmengine/oemcrypto/odk/src/odk.c b/libwvdrmengine/oemcrypto/odk/src/odk.c index 5faa2de6..3f4090f2 100644 --- a/libwvdrmengine/oemcrypto/odk/src/odk.c +++ b/libwvdrmengine/oemcrypto/odk/src/odk.c @@ -239,6 +239,10 @@ OEMCryptoResult ODK_PrepareCoreReleaseRequest( uint32_t clock_security_level, int64_t seconds_since_license_requested, int64_t seconds_since_first_decrypt, ODK_ClockValues* clock_values, uint64_t system_time_seconds) { + (void)status; + (void)clock_security_level; + (void)seconds_since_license_requested; + (void)seconds_since_first_decrypt; if (core_message_size == NULL || nonce_values == NULL || clock_values == NULL) { return ODK_ERROR_CORE_MESSAGE; From fb1554a10bc8e30de58c2ebb6fad3f1b232a90fa Mon Sep 17 00:00:00 2001 From: Matt Feddersen Date: Fri, 22 Mar 2024 11:41:40 -0700 Subject: [PATCH 4/8] Lock v19.1 API Merged from https://widevine-internal-review.googlesource.com/195130 Change-Id: I44760c19bc1457017ffacdda5f3c40f4a66edccb --- libwvdrmengine/oemcrypto/test/GEN_api_lock_file.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libwvdrmengine/oemcrypto/test/GEN_api_lock_file.c b/libwvdrmengine/oemcrypto/test/GEN_api_lock_file.c index b796610b..1822df9d 100644 --- a/libwvdrmengine/oemcrypto/test/GEN_api_lock_file.c +++ b/libwvdrmengine/oemcrypto/test/GEN_api_lock_file.c @@ -419,3 +419,9 @@ OEMCryptoResult _oecc148(OEMCrypto_SESSION session, // OEMCrypto_SetDecryptHash defined in v19.0 OEMCryptoResult _oecc143(OEMCrypto_SESSION session, uint32_t frame_number, uint32_t crc32); + +// OEMCrypto_GetEmbeddedDrmCertificate defined in v19.1 +OEMCryptoResult _oecc151(uint8_t* public_cert, size_t* public_cert_length); + +// OEMCrypto_UseSecondaryKey defined in v19.1 +OEMCryptoResult _oecc152(OEMCrypto_SESSION session_id, bool dual_key); From d05d3738b4fa448ec5d4688b24d3e7f41427f177 Mon Sep 17 00:00:00 2001 From: Vicky Min Date: Tue, 19 Mar 2024 18:37:32 +0000 Subject: [PATCH 5/8] Integration tests to verify clear lead content plays successfully Also added a unit test to verify that decryption without a license fails with the correct error code. Also changed comment types for policy integration tests and core integration tests to be picked up by Doxygen. Bug: 320785945 Merged from https://widevine-internal-review.googlesource.com/194910 Change-Id: Ibdb70683003bb430dde9b4a1bd9fc9839bace342 --- .../cdm/core/test/core_integration_test.cpp | 49 +++++++++++++++++-- .../cdm/core/test/license_holder.cpp | 14 ++++++ libwvdrmengine/cdm/core/test/license_holder.h | 3 ++ .../cdm/core/test/policy_integration_test.cpp | 30 ++++++++---- 4 files changed, 83 insertions(+), 13 deletions(-) diff --git a/libwvdrmengine/cdm/core/test/core_integration_test.cpp b/libwvdrmengine/cdm/core/test/core_integration_test.cpp index ae267b6f..9e7a7186 100644 --- a/libwvdrmengine/cdm/core/test/core_integration_test.cpp +++ b/libwvdrmengine/cdm/core/test/core_integration_test.cpp @@ -3,6 +3,7 @@ // Agreement. #include "certificate_provisioning.h" +#include "license_holder.h" #include "log.h" #include "provisioning_holder.h" #include "test_base.h" @@ -128,9 +129,11 @@ class CoreIntegrationTest : public WvCdmTestBaseWithEngine { } }; -// Verify that SPOIDs and DRM certificate serial number are stable between -// factory resets/provisioning attempts for the same app and different between -// different apps. Test using two different apps and origins. +/** + * Verify that SPOIDs and DRM certificate serial number are stable between + * factory resets/provisioning attempts for the same app and different between + * different apps. Test using two different apps and origins. + */ TEST_F(CoreIntegrationTest, ProvisioningStableSpoidTest) { std::string level; ASSERT_EQ( @@ -233,4 +236,44 @@ TEST_F(CoreIntegrationTest, ProvisioningStableSpoidTest) { ASSERT_NE(drm_cert_serial_number_app_1_origin_1[0], drm_cert_serial_number_app_1_origin_2[0]); } + +/** + * A clear lead without a license loaded. + */ +TEST_F(CoreIntegrationTest, ClearLead) { + LicenseHolder holder("CDM_Streaming", &cdm_engine_, config_); + const KeyId key_id = ""; + + ASSERT_NO_FATAL_FAILURE(holder.OpenSession()); + ASSERT_NO_FATAL_FAILURE(holder.FetchLicense()); + EXPECT_EQ(NO_ERROR, holder.DecryptClearLead(key_id)); + ASSERT_NO_FATAL_FAILURE(holder.CloseSession()); +} + +/** + * Playback clear lead with a license loaded. Playback should succeed. + */ +TEST_F(CoreIntegrationTest, ClearLeadAfterLicenseLoad) { + LicenseHolder holder("CDM_Streaming", &cdm_engine_, config_); + const KeyId key_id = ""; + + ASSERT_NO_FATAL_FAILURE(holder.OpenSession()); + ASSERT_NO_FATAL_FAILURE(holder.FetchLicense()); + ASSERT_NO_FATAL_FAILURE(holder.LoadLicense()); + EXPECT_EQ(NO_ERROR, holder.DecryptClearLead(key_id)); + ASSERT_NO_FATAL_FAILURE(holder.CloseSession()); +} + +/** + * Decrypt without a license loaded. Decrypt should fail with a NEED_KEY error. + */ +TEST_F(CoreIntegrationTest, NeedKeyBeforeLicenseLoad) { + LicenseHolder holder("CDM_Streaming", &cdm_engine_, config_); + const KeyId key_id = "0000000000000000"; + + ASSERT_NO_FATAL_FAILURE(holder.OpenSession()); + ASSERT_NO_FATAL_FAILURE(holder.FetchLicense()); + EXPECT_EQ(NEED_KEY, holder.Decrypt(key_id)); + ASSERT_NO_FATAL_FAILURE(holder.CloseSession()); +} } // namespace wvcdm diff --git a/libwvdrmengine/cdm/core/test/license_holder.cpp b/libwvdrmengine/cdm/core/test/license_holder.cpp index 30300593..0e9837b7 100644 --- a/libwvdrmengine/cdm/core/test/license_holder.cpp +++ b/libwvdrmengine/cdm/core/test/license_holder.cpp @@ -176,6 +176,20 @@ CdmResponseType LicenseHolder::Decrypt(const std::string& key_id) { return cdm_engine_->DecryptV16(session_id_, params); } +CdmResponseType LicenseHolder::DecryptClearLead(const std::string& key_id) { + constexpr size_t buffer_size = 500; + const std::vector input(buffer_size, 0); + std::vector output(buffer_size, 0); + const std::vector iv(KEY_IV_SIZE, 0); + CdmDecryptionParametersV16 params(key_id); + params.is_secure = false; + CdmDecryptionSample sample(input.data(), output.data(), 0, input.size(), iv); + CdmDecryptionSubsample subsample(input.size(), 0); + sample.subsamples.push_back(subsample); + params.samples.push_back(sample); + return cdm_engine_->DecryptV16(session_id_, params); +} + void LicenseHolder::DecryptSecure(const KeyId& key_id) { ASSERT_TRUE(wvoec::global_features.test_secure_buffers); constexpr size_t buffer_size = 500; diff --git a/libwvdrmengine/cdm/core/test/license_holder.h b/libwvdrmengine/cdm/core/test/license_holder.h index 41578567..405af278 100644 --- a/libwvdrmengine/cdm/core/test/license_holder.h +++ b/libwvdrmengine/cdm/core/test/license_holder.h @@ -86,6 +86,9 @@ class LicenseHolder { // Try to decrypt some random data. This does not verify that the data is // decrypted correctly. Returns the result of the decrypt operation. CdmResponseType Decrypt(const std::string& key_id); + // Try to copy the clear lead to a secure buffer. Returns the result of the + // copy buffer operation. + CdmResponseType DecryptClearLead(const std::string& key_id); // Try to decrypt some random data to a secure buffer. If the test harness // does not allow creating a secure buffer, then this function fails // immediately. Otherwise, a secure buffer is created and used for a diff --git a/libwvdrmengine/cdm/core/test/policy_integration_test.cpp b/libwvdrmengine/cdm/core/test/policy_integration_test.cpp index ed523ff6..814b6d07 100644 --- a/libwvdrmengine/cdm/core/test/policy_integration_test.cpp +++ b/libwvdrmengine/cdm/core/test/policy_integration_test.cpp @@ -35,7 +35,9 @@ class CorePIGTest : public WvCdmTestBaseWithEngine { } }; -// An offline license with nonce not required. +/** + * An offline license with nonce not required. + */ TEST_F(CorePIGTest, OfflineNoNonce) { LicenseHolder holder("CDM_OfflineNoNonce", &cdm_engine_, config_); holder.set_can_persist(true); @@ -54,7 +56,9 @@ TEST_F(CorePIGTest, OfflineNoNonce) { ASSERT_NO_FATAL_FAILURE(holder.CloseSession()); } -// An offline license with nonce and provider session token. +/** + * An offline license with nonce and provider session token. + */ TEST_F(CorePIGTest, OfflineWithPST) { LicenseHolder holder("CDM_OfflineWithPST", &cdm_engine_, config_); holder.set_can_persist(true); @@ -128,10 +132,12 @@ TEST_F(CorePIGTest, OfflineMultipleLicensesWithDefrag) { ASSERT_NO_FATAL_FAILURE(holder3.CloseSession()); } -// This test verifies that the system can download and install license with a -// key that requires secure buffers. It also verifies that we cannot decrypt to -// a non-secure buffer using this key, but that we can decrypt to a secure -// buffer, if the test harness supports secure buffers. +/** + * This test verifies that the system can download and install license with a + * key that requires secure buffers. It also verifies that we cannot decrypt to + * a non-secure buffer using this key, but that we can decrypt to a secure + * buffer, if the test harness supports secure buffers. + */ TEST_F(CorePIGTest, OfflineHWSecureRequired) { LicenseHolder holder("CDM_OfflineHWSecureRequired", &cdm_engine_, config_); holder.set_can_persist(true); @@ -170,8 +176,10 @@ TEST_F(CorePIGTest, OfflineHWSecureRequired) { ASSERT_NO_FATAL_FAILURE(holder.CloseSession()); } -// Should be able to request license, perform playback, generate a license -// release, and receive the release response. +/** + * Should be able to request license, perform playback, generate a license + * release, and receive the release response. + */ TEST_F(CorePIGTest, LicenseRelease1) { if (!wvoec::global_features.usage_table) { GTEST_SKIP() << "Test for usage table devices only."; @@ -194,8 +202,10 @@ TEST_F(CorePIGTest, LicenseRelease1) { ASSERT_NO_FATAL_FAILURE(holder.CloseSession()); } -// Should be able to request license, wait some time, generate a license -// release, and receive the release response. +/** + * Should be able to request license, wait some time, generate a license + * release, and receive the release response. + */ TEST_F(CorePIGTest, LicenseRelease2) { if (!wvoec::global_features.usage_table) { GTEST_SKIP() << "Test for usage table devices only."; From daa6f5f73829bfd50f1f60a43d1832c3d65eade2 Mon Sep 17 00:00:00 2001 From: Matt Feddersen Date: Thu, 21 Mar 2024 14:11:23 -0700 Subject: [PATCH 6/8] Bump version to 19.1.0 and update OPK changelog Merged from https://widevine-internal-review.googlesource.com/194911 Change-Id: I366df6f46622d6333e7f77cbef3cb5dc9b1d2710 --- libwvdrmengine/oemcrypto/CHANGELOG.md | 49 +++++++++++++++++++ .../oemcrypto/include/OEMCryptoCENC.h | 2 +- .../oemcrypto/test/oemcrypto_basic_test.cpp | 4 +- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/libwvdrmengine/oemcrypto/CHANGELOG.md b/libwvdrmengine/oemcrypto/CHANGELOG.md index 449db2c0..d13448ea 100644 --- a/libwvdrmengine/oemcrypto/CHANGELOG.md +++ b/libwvdrmengine/oemcrypto/CHANGELOG.md @@ -2,6 +2,54 @@ [TOC] +## [Version 19.1][v19.1] + +This is a minor release that includes a few security fixes and bug fixes. + +General + +- Change OEMCrypto_FreeSecureBuffer() |output_descriptor| parameter to be +[in,out] type. +- Use strlen() instead of sizeof() to get the length of BUILD_INFO. +- Add OEMCrypto_GetEmbeddedDrmCertificate() definition to OPK, with +OEMCrypto_ERROR_NOT_IMPLEMENTED. +- Remove default.h include file from wtpi_config, which was causing a mismatch +between reported config values and actual config values. +- Remove extra is_debug field and trailing comma from BuildInformation. +- Reduce trusted clock skew on restarts in wtpi_reference implementation. +- Remove -Wno-unused-parameter cflag. +- Increase transport buffer size from 32K to 34K to accommodate larger buffer +requirements from OEMCrypto_LoadProvisioning +- Fix BCC payload item count in wtpi_reference +- Add WTPI_DeriveNewAsymmetricKeyHandle() and +WTPI_CreateUDSDerivedAsymmetricKeyHandle() to wtpi_provisioning_4_interface.h. +These implementations are only required if you are using +wtpi_reference/wtpi_provisioning_4.c. + +OPK serialization layer + +- Avoid writing any value to output parameters if the OEMCryptoResult is not +OEMCrypto_SUCCESS. (Applies to [out] type only. Not [in] or [in,out]). This +avoids subtle bugs where the serialization logic may unexpectedly modify (eg +set to 0) an output parameter on failure. +- Initialize pointers in a few corner cases. + +Tests + +- Fix default cipher mode for CAS unit test. +- Skip entitlement session tests that are only supported on CAS devices. +- Don't force decrypt count to increase in unit tests. +- Skip some cast tests if not supported. + +OP-TEE port changes + +- Fix memory leaks on failure cases in AES decrypt, RSA key creation, and ECC +key creation. +- Check incoming message size from REE to avoid OOB. +- Generate ECC keypair and zero pad appropriately. +- Add file existence check in RPMB impl. +- Cleanup keybox and key handles consistently after use. + ## [Version 19.0][v19.0] This is the initial release of OPK v19.0, which implements OEMCrypto v19.0. @@ -542,3 +590,4 @@ Public release for OEMCrypto API and ODK library version 16.4. [v18.3]: https://widevine-partner.googlesource.com/oemcrypto/+/refs/tags/v18.3 [v18.4]: https://widevine-partner.googlesource.com/oemcrypto/+/refs/tags/v18.4 [v19.0]: https://widevine-partner.googlesource.com/oemcrypto/+/refs/tags/v19.0 +[v19.1]: https://widevine-partner.googlesource.com/oemcrypto/+/refs/tags/v19.1 diff --git a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h index a1f25831..f845a876 100644 --- a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h +++ b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h @@ -3,7 +3,7 @@ // License Agreement. /** - * @mainpage OEMCrypto API v19.0 + * @mainpage OEMCrypto API v19.1 * * OEMCrypto is the low level library implemented by the OEM to provide key and * content protection, usually in a separate secure memory or process space. The diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_basic_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_basic_test.cpp index ef0f18ae..0d669262 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_basic_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_basic_test.cpp @@ -180,7 +180,7 @@ TEST_F(OEMCryptoClientTest, FreeUnallocatedSecureBufferNoFailure) { */ TEST_F(OEMCryptoClientTest, VersionNumber) { const std::string log_message = - "OEMCrypto unit tests for API 19.0. Tests last updated 2023-12-14"; + "OEMCrypto unit tests for API 19.1. Tests last updated 2024-03-25"; cout << " " << log_message << "\n"; cout << " " << "These tests are part of Android U." @@ -189,7 +189,7 @@ TEST_F(OEMCryptoClientTest, VersionNumber) { // If any of the following fail, then it is time to update the log message // above. EXPECT_EQ(ODK_MAJOR_VERSION, 19); - EXPECT_EQ(ODK_MINOR_VERSION, 0); + EXPECT_EQ(ODK_MINOR_VERSION, 1); EXPECT_EQ(kCurrentAPI, static_cast(ODK_MAJOR_VERSION)); OEMCrypto_Security_Level level = OEMCrypto_SecurityLevel(); EXPECT_GT(level, OEMCrypto_Level_Unknown); From 688a572357e7710f6ea0f94d83788acd8ca6e496 Mon Sep 17 00:00:00 2001 From: Shawn Willden Date: Mon, 1 Apr 2024 10:24:45 -0600 Subject: [PATCH 7/8] Remove unnecessary "_external" suffix from libcppbor Test: Build Change-Id: I8e4d65bafe9d4b4bbc576c8c9c995bddf0a957a2 --- libwvdrmengine/factory_upload_tool/Android.bp | 2 +- libwvdrmengine/oemcrypto/test/common.mk | 2 +- libwvdrmengine/tools/factory_upload_tool/Android.bp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libwvdrmengine/factory_upload_tool/Android.bp b/libwvdrmengine/factory_upload_tool/Android.bp index a458cb6b..cb5d221c 100644 --- a/libwvdrmengine/factory_upload_tool/Android.bp +++ b/libwvdrmengine/factory_upload_tool/Android.bp @@ -26,7 +26,7 @@ cc_binary { "android.hardware.security.rkp-V3-ndk", "libbase", "libbinder_ndk", - "libcppbor_external", + "libcppbor", "libcrypto", "libkeymaster_portable", "libkeymint", diff --git a/libwvdrmengine/oemcrypto/test/common.mk b/libwvdrmengine/oemcrypto/test/common.mk index 054127cb..9c0b3515 100644 --- a/libwvdrmengine/oemcrypto/test/common.mk +++ b/libwvdrmengine/oemcrypto/test/common.mk @@ -62,7 +62,7 @@ LOCAL_STATIC_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \ libbase \ - libcppbor_external \ + libcppbor \ libcrypto \ libdl \ libbinder_ndk \ diff --git a/libwvdrmengine/tools/factory_upload_tool/Android.bp b/libwvdrmengine/tools/factory_upload_tool/Android.bp index 8346c087..f5db00dd 100644 --- a/libwvdrmengine/tools/factory_upload_tool/Android.bp +++ b/libwvdrmengine/tools/factory_upload_tool/Android.bp @@ -20,7 +20,7 @@ cc_binary { ], shared_libs: [ "libbase", - "libcppbor_external", + "libcppbor", "libcppcose_rkp", "libcrypto", "liblog", From d9079fb300980ec88d2fa584ee6f5550dd018271 Mon Sep 17 00:00:00 2001 From: Kalesh Singh Date: Wed, 27 Mar 2024 13:19:35 -0700 Subject: [PATCH 8/8] widevine_generic: Set max page size 16k Bug: 322391670 Change-Id: Ic5a9c6e33e675d33138127915c6ab9910742f6d7 Signed-off-by: Kalesh Singh --- libwvdrmengine/apex/device/widevine_generic.mk | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libwvdrmengine/apex/device/widevine_generic.mk b/libwvdrmengine/apex/device/widevine_generic.mk index e16ddb80..6a9694a5 100644 --- a/libwvdrmengine/apex/device/widevine_generic.mk +++ b/libwvdrmengine/apex/device/widevine_generic.mk @@ -5,4 +5,8 @@ else $(call inherit-product, $(SRC_TARGET_DIR)/product/module_arm.mk) endif +# Enable large page size support +PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384 +PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true + include vendor/widevine/libwvdrmengine/apex/device/device.mk