diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_types.h b/libwvdrmengine/cdm/core/include/wv_cdm_types.h index e14a02ea..5a5a12db 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_types.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_types.h @@ -607,7 +607,9 @@ enum CdmClientTokenType : int32_t { kClientTokenOemCert, kClientTokenUninitialized, kClientTokenBootCertChain, - kClientTokenDrmReprovisioning, + // For use by internal L3 CDMs supporting individualization of embedded + // drm certificates. + kClientTokenDrmCertificateReprovisioning, }; // kNonSecureUsageSupport - TEE does not provide any support for usage diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index ce1170da..d0e26d61 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -754,7 +754,7 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, } switch (token_type) { case kClientTokenDrmCert: - case kClientTokenDrmReprovisioning: + case kClientTokenDrmCertificateReprovisioning: *query_response = QUERY_VALUE_DRM_CERTIFICATE; break; case kClientTokenKeybox: diff --git a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp index 38973baf..b40c3825 100644 --- a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp +++ b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp @@ -169,7 +169,7 @@ CertificateProvisioning::GetProvisioningType() { return SignedProvisioningMessage::PROVISIONING_40; case kClientTokenOemCert: return SignedProvisioningMessage::PROVISIONING_30; - case kClientTokenDrmReprovisioning: + case kClientTokenDrmCertificateReprovisioning: return SignedProvisioningMessage::DRM_REPROVISIONING; default: return SignedProvisioningMessage::PROVISIONING_20; diff --git a/libwvdrmengine/cdm/core/src/client_identification.cpp b/libwvdrmengine/cdm/core/src/client_identification.cpp index 86aa9fff..94bb8720 100644 --- a/libwvdrmengine/cdm/core/src/client_identification.cpp +++ b/libwvdrmengine/cdm/core/src/client_identification.cpp @@ -404,7 +404,7 @@ bool ClientIdentification::GetProvisioningTokenType( } return true; } - case kClientTokenDrmReprovisioning: + case kClientTokenDrmCertificateReprovisioning: *token_type = video_widevine::ClientIdentification::DRM_DEVICE_CERTIFICATE; return true; diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index ee60c5e1..939af6dd 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -348,7 +348,7 @@ CdmResponseType CryptoSession::GetProvisioningMethod( type = kClientTokenBootCertChain; break; case OEMCrypto_DrmReprovisioning: - type = kClientTokenDrmReprovisioning; + type = kClientTokenDrmCertificateReprovisioning; break; case OEMCrypto_ProvisioningError: default: @@ -666,7 +666,8 @@ CdmResponseType CryptoSession::GetProvisioningToken( } else if (pre_provision_token_type_ == kClientTokenBootCertChain) { status = GetBootCertificateChain(requested_security_level, token, additional_token); - } else if (pre_provision_token_type_ == kClientTokenDrmReprovisioning) { + } else if (pre_provision_token_type_ == + kClientTokenDrmCertificateReprovisioning) { status = GetTokenFromEmbeddedCertificate(token); } metrics_->crypto_session_get_token_.Increment(status); @@ -1275,7 +1276,8 @@ CdmResponseType CryptoSession::PrepareAndSignProvisioningRequest( should_specify_algorithm = true; // Do nothing here. The key to signing the provisioning 4.0 request for each // stage has been loaded already when it was generated by OEMCrypto. - } else if (pre_provision_token_type_ == kClientTokenDrmReprovisioning) { + } else if (pre_provision_token_type_ == + kClientTokenDrmCertificateReprovisioning) { should_specify_algorithm = false; // Do nothing here. The baked-in certificate used as the token has already // been loaded when the EncryptedClientId was filled in. @@ -1462,7 +1464,7 @@ CdmResponseType CryptoSession::GetTokenFromEmbeddedCertificate( LOGE("Failed to get token type"); return sts; } - if (token_type != kClientTokenDrmReprovisioning) { + if (token_type != kClientTokenDrmCertificateReprovisioning) { token->clear(); return CdmResponseType(NO_ERROR); } diff --git a/libwvdrmengine/cdm/core/src/device_files.proto b/libwvdrmengine/cdm/core/src/device_files.proto index 7b4a02ef..caf93563 100644 --- a/libwvdrmengine/cdm/core/src/device_files.proto +++ b/libwvdrmengine/cdm/core/src/device_files.proto @@ -20,6 +20,10 @@ message NameValue { optional string value = 2; } +message SavedStorage { + map files = 1; +} + message OemCertificate { enum PrivateKeyType { RSA = 0; diff --git a/libwvdrmengine/cdm/core/src/license_protocol.proto b/libwvdrmengine/cdm/core/src/license_protocol.proto index 70c778c3..7e814b54 100644 --- a/libwvdrmengine/cdm/core/src/license_protocol.proto +++ b/libwvdrmengine/cdm/core/src/license_protocol.proto @@ -1026,7 +1026,8 @@ message SignedProvisioningMessage { ARCPP_PROVISIONING = 4; // ChromeOS/Arc++ devices. // Android-Attestation-based OTA keyboxes. ANDROID_ATTESTATION_KEYBOX_OTA = 6; - // Certificate reprovisioning for internal L3 CDMs only. + // DRM certificate reprovisioning for individualization of embedded + // DRM certificates used by internal L3 CDMs only. DRM_REPROVISIONING = 7; INTEL_SIGMA_101 = 101; // Intel Sigma 1.0.1 protocol. INTEL_SIGMA_210 = 210; // Intel Sigma 2.1.0 protocol. @@ -1275,8 +1276,9 @@ message DrmCertificate { DEVICE = 2; SERVICE = 3; PROVISIONER = 4; - // Only used by baked-in certificates with internal L3 CDMs that support - // Drm Reprovisioning. + // Only used by internal L3 CDMs with baked-in (embedded) certificates that + // support the Drm Reprovisioning method for individualization of embedded + // certificates. DEVICE_EMBEDDED = 5; } enum ServiceType { diff --git a/libwvdrmengine/cdm/core/src/system_id_extractor.cpp b/libwvdrmengine/cdm/core/src/system_id_extractor.cpp index 791ace5f..72b548fd 100644 --- a/libwvdrmengine/cdm/core/src/system_id_extractor.cpp +++ b/libwvdrmengine/cdm/core/src/system_id_extractor.cpp @@ -60,7 +60,7 @@ bool SystemIdExtractor::ExtractSystemId(uint32_t* system_id) { switch (type) { case kClientTokenDrmCert: // TODO: b/309675153 - Extract system id when using DRM reprovisioning. - case kClientTokenDrmReprovisioning: + case kClientTokenDrmCertificateReprovisioning: LOGW( "Cannot get a system ID from a DRM certificate, " "using null system ID: security_level = %s", diff --git a/libwvdrmengine/cdm/core/src/wv_cdm_types.cpp b/libwvdrmengine/cdm/core/src/wv_cdm_types.cpp index ce21bd81..edc2edf2 100644 --- a/libwvdrmengine/cdm/core/src/wv_cdm_types.cpp +++ b/libwvdrmengine/cdm/core/src/wv_cdm_types.cpp @@ -76,8 +76,8 @@ const char* CdmClientTokenTypeToString(CdmClientTokenType type) { return "BootCertChain"; case kClientTokenUninitialized: return "Uninitialized"; - case kClientTokenDrmReprovisioning: - return "DrmReprovisioning"; + case kClientTokenDrmCertificateReprovisioning: + return "DrmCertificateReprovisioning"; } return UnknownValueRep(type); } diff --git a/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp b/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp index 274015ec..074cf343 100644 --- a/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp +++ b/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp @@ -119,13 +119,6 @@ class WvCdmEnginePreProvTest : public WvCdmTestBaseWithEngine { std::string session_id_; }; -class WvCdmEnginePreProvTestStaging : public WvCdmEnginePreProvTest { - public: - WvCdmEnginePreProvTestStaging() { - config_ = ConfigTestEnv(kContentProtectionStagingServer); - } -}; - class WvCdmEnginePreProvTestProd : public WvCdmEnginePreProvTest { public: WvCdmEnginePreProvTestProd() { @@ -342,8 +335,6 @@ TEST_F(WvCdmEngineTest, SetLicensingServiceInvalidCertificate) { NO_ERROR); }; -TEST_F(WvCdmEnginePreProvTestStaging, ProvisioningTest) { EnsureProvisioned(); } - TEST_F(WvCdmEnginePreProvTestUatBinary, ProvisioningTest) { EnsureProvisioned(); } diff --git a/libwvdrmengine/cdm/core/test/certificate_provisioning_unittest.cpp b/libwvdrmengine/cdm/core/test/certificate_provisioning_unittest.cpp index cf5ccbd9..01328861 100644 --- a/libwvdrmengine/cdm/core/test/certificate_provisioning_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/certificate_provisioning_unittest.cpp @@ -482,7 +482,7 @@ TEST_P(CertificateProvisioningTest, ProvisioningResponseSuccess) { INSTANTIATE_TEST_SUITE_P( CertificateProvisioningTests, CertificateProvisioningTest, testing::Values(kClientTokenKeybox, kClientTokenOemCert, - kClientTokenDrmReprovisioning), + kClientTokenDrmCertificateReprovisioning), [](const testing::TestParamInfo& param_type) { return CdmClientTokenTypeToString(param_type.param); diff --git a/libwvdrmengine/cdm/core/test/crypto_session_unittest.cpp b/libwvdrmengine/cdm/core/test/crypto_session_unittest.cpp index 138cbff2..a668481d 100644 --- a/libwvdrmengine/cdm/core/test/crypto_session_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/crypto_session_unittest.cpp @@ -99,7 +99,7 @@ TEST_F(CryptoSessionMetricsTest, OpenSessionValidMetrics) { } else if (token_type == kClientTokenBootCertChain) { EXPECT_EQ(OEMCrypto_BootCertificateChain, metrics_proto.oemcrypto_provisioning_method().int_value()); - } else if (token_type == kClientTokenDrmReprovisioning) { + } else if (token_type == kClientTokenDrmCertificateReprovisioning) { EXPECT_EQ(OEMCrypto_DrmReprovisioning, metrics_proto.oemcrypto_provisioning_method().int_value()); } else { @@ -143,7 +143,7 @@ TEST_F(CryptoSessionMetricsTest, GetProvisioningTokenValidMetrics) { } else if (token_type == kClientTokenBootCertChain) { EXPECT_EQ(OEMCrypto_BootCertificateChain, metrics_proto.oemcrypto_provisioning_method().int_value()); - } else if (token_type == kClientTokenDrmReprovisioning) { + } else if (token_type == kClientTokenDrmCertificateReprovisioning) { EXPECT_EQ(OEMCrypto_DrmReprovisioning, metrics_proto.oemcrypto_provisioning_method().int_value()); } else { diff --git a/libwvdrmengine/cdm/core/test/duration_use_case_test.cpp b/libwvdrmengine/cdm/core/test/duration_use_case_test.cpp index 7346e510..e9c003ef 100644 --- a/libwvdrmengine/cdm/core/test/duration_use_case_test.cpp +++ b/libwvdrmengine/cdm/core/test/duration_use_case_test.cpp @@ -128,6 +128,12 @@ class CdmDurationTest : public WvCdmTestBaseWithEngine, // appended to it. void SetUp() override { WvCdmTestBase::SetUp(); + // TODO: b/305093063 - Remove when Drm Reprovisioning server is implemented. + if (wvoec::global_features.provisioning_method == + OEMCrypto_DrmReprovisioning) { + GTEST_SKIP() + << "Skipping until Drm Reprovisioning server support is implemented."; + } EnsureProvisioned(); license_holder_.set_can_persist(GetParam()); ASSERT_NO_FATAL_FAILURE(license_holder_.OpenSession()); @@ -152,6 +158,14 @@ class CdmDurationTest : public WvCdmTestBaseWithEngine, } void TearDown() override { + // TODO: b/305093063 - Remove when Drm Reprovisioning server is implemented. + if (wvoec::global_features.provisioning_method == + OEMCrypto_DrmReprovisioning) { + // Since the session was not opened above. We can skip closing the session + // here too. This should be removed when EnsureProvisioning no longer + // skips this test. + return; + } license_holder_.CloseSession(); // Log the time used in this test suite. When this comment was written, // these tests took over three hours. If we want to improve that, we need to diff --git a/libwvdrmengine/cdm/core/test/provisioning_holder.cpp b/libwvdrmengine/cdm/core/test/provisioning_holder.cpp index 954b2eff..697beb97 100644 --- a/libwvdrmengine/cdm/core/test/provisioning_holder.cpp +++ b/libwvdrmengine/cdm/core/test/provisioning_holder.cpp @@ -185,6 +185,7 @@ std::string ProvisioningHolder::DumpProvAttempt(const std::string& request, if (result != OEMCrypto_SUCCESS) { info << "--- ERROR GETTING BCC. result=" << result; } else { + bcc.resize(bcc_length); info << "BCC = (len=" << bcc_length << ") " << wvutil::unlimited_b2a_hex(bcc) << "\n" << "Additional Sig = (len=" << signature_length << ") " diff --git a/libwvdrmengine/cdm/core/test/reboot_test.cpp b/libwvdrmengine/cdm/core/test/reboot_test.cpp index 3e5ce5fe..1e4f61f2 100644 --- a/libwvdrmengine/cdm/core/test/reboot_test.cpp +++ b/libwvdrmengine/cdm/core/test/reboot_test.cpp @@ -11,14 +11,14 @@ #include #include "create_test_file_system.h" +#include "device_files.pb.h" #include "license_holder.h" #include "log.h" #include "test_sleep.h" -using wvutil::a2b_hex; +using video_widevine_client::sdk::SavedStorage; using wvutil::FileSystem; using wvutil::TestSleep; -using wvutil::unlimited_b2a_hex; namespace wvcdm { FileSystem* RebootTest::file_system_; @@ -27,179 +27,8 @@ namespace { // How much fudge or round off error do we allow in license durations for reboot // tests. constexpr int64_t kFudge = 10; - -// We will encode a value string by wrapping it in braces, or as hex. -// If the string is not printable, or if it has unmatched braces, then we use -// hex. Otherwise, we surround the whole string with braces. -std::string EncodeString(const std::string& data) { - int braces_count = 0; - for (size_t i = 0; i < data.length(); i++) { - if (data[i] == '{') braces_count++; - if (data[i] == '}') braces_count--; - // If printable or whitespace (because '\n' is not printable?!?). - bool printable = isprint(data[i]) || isspace(data[i]); - // If there are any unprintable characters, except whitespace, or if we - // close a brace before we open it, then just use hex. - if (!printable || braces_count < 0) { - return "0x" + unlimited_b2a_hex(data) + ","; - } - } - // If we left any braces open, then use hex. - if (braces_count != 0) return "0x" + unlimited_b2a_hex(data) + ","; - return "{" + data + "},"; -} - -// Encode a map key for dumping. When we encode a map, we expect the keys to be -// like filenames, so we can separate them with colons and whitespace. If the -// key has these special characters, we will encode as hex. -std::string EncodeKey(const std::string& data) { - if (data.length() == 0) { - LOGE("Encoding empty string as key!"); - return "EMPTY:"; - } - // When decoding, we assume that a key starting with "0x" is in hex. So we - // can't have any keys that start with "0x". - if (data.substr(0, 2) == "0x") return "0x" + unlimited_b2a_hex(data) + ":"; - // If the key is just is not printable, or if it has unmatched braces, then - // we use hex. Otherwise, we surround the whole string with braces. - for (size_t i = 0; i < data.length(); i++) { - if (!isprint(data[i]) || (data[i] == ':')) { - return "0x" + unlimited_b2a_hex(data) + ":"; - } - } - return data + ":"; -} - -// In between keys and values, we will ignore whitespace. This allows a human to -// edit the persistent data a little bit without breaking anything. -void SkipSpace(const std::string& encoded, size_t* index) { - if (!index) return; - while (*index < encoded.length() && isspace(encoded[*index])) (*index)++; -} - -// Decode a string that was encoded using EncodeString. -std::string DecodeString(const std::string& encoded, size_t* index) { - if (!index) return ""; - SkipSpace(encoded, index); - if (*index + 2 >= - encoded.length()) { // Encoded string has at least 3 characters. - LOGE("Error decoding short string from %s at %zd", encoded.c_str(), *index); - *index = encoded.length(); - return ""; - } - if (encoded[*index] == '{') { - (*index)++; - size_t start = *index; - int braces_count = 1; - while (*index < encoded.length()) { - if (encoded[*index] == '{') braces_count++; - if (encoded[*index] == '}') braces_count--; - if (braces_count == 0) { - size_t end = *index; - (*index) += 2; // absorb the comma and the '}', too. - return encoded.substr(start, end - start); - } - (*index)++; - } - std::string tail = encoded.substr(start); - LOGE("Non-terminated brace %s at %zd: %s", encoded.c_str(), start, - tail.c_str()); - *index = encoded.length(); - return ""; - } - if (encoded[*index] != '0' || encoded[*index + 1] != 'x') { - std::string tail = encoded.substr(*index); - LOGE("Hex should start with 0x in %s at %zd: %s", encoded.c_str(), *index, - tail.c_str()); - *index = encoded.length(); - return ""; - } - *index += 2; - size_t start = *index; - while (*index < encoded.length()) { - if (encoded[*index] == ',') { - size_t end = *index; - std::vector result = a2b_hex(encoded.substr(start, end - start)); - (*index)++; // absorb the comma. - return std::string(result.begin(), result.end()); - } - (*index)++; - } - std::string tail = encoded.substr(start); - LOGE("Bad encoding in %s at %zd: %s", encoded.c_str(), start, tail.c_str()); - *index = encoded.length(); - return ""; -} - -// Decode a string that was encoded with EncodeKey. -std::string DecodeKey(const std::string& encoded, size_t* index) { - if (!index) return ""; - SkipSpace(encoded, index); - if (*index + 1 >= encoded.length()) { - LOGE("Error decoding key from %s at %zd", encoded.c_str(), *index); - *index = encoded.length(); - return ""; - } - // If it starts with 0x, then it is in hex. - if (encoded[*index] == '0' && encoded[*index + 1] == 'x') { - size_t start = *index + 2; - while (*index < encoded.length() && encoded[*index] != ':') (*index)++; - size_t end = *index; - std::vector result = a2b_hex(encoded.substr(start, end - start)); - (*index)++; // skip the colon. - return std::string(result.begin(), result.end()); - } - size_t start = *index; - while (*index < encoded.length() && encoded[*index] != ':') (*index)++; - size_t end = *index; - (*index)++; // skip the colon. - return encoded.substr(start, end - start); -} } // namespace -std::string RebootTest::DumpData( - const std::map& data) { - std::ostringstream output; - output << "{\n"; - for (const auto& entry : data) { - output << " " << EncodeKey(entry.first) << " " - << EncodeString(entry.second) + "\n"; - } - output << "}\n"; - return output.str(); -} - -bool RebootTest::ParseDump(const std::string& dump, - std::map* data) { - size_t index = 0; - SkipSpace(dump, &index); - if (index >= dump.length()) return false; - if (dump[index] != '{') { - LOGE("Dump does not start with '{'"); - return false; - } - index++; // absorb '{' - while (true) { - SkipSpace(dump, &index); - if (index >= dump.length()) return false; - if (dump[index] == '}') { - index++; // absorb '}' - SkipSpace(dump, &index); - if (index != dump.length()) { - std::string tail = dump.substr(index); - LOGE("Trailing data in dump. %s at %zd: %s", dump.c_str(), index, - tail.c_str()); - return false; - } - return true; - } - std::string tail = dump.substr(index); - std::string key = DecodeKey(dump, &index); - std::string value = DecodeString(dump, &index); - (*data)[key] = value; - } -} - void RebootTest::SetUp() { WvCdmTestBase::SetUp(); if (!file_system_) file_system_ = CreateTestFileSystem(); @@ -221,7 +50,10 @@ void RebootTest::SetUp() { std::string dump(file_size, ' '); ssize_t read = file->Read(&dump[0], dump.size()); EXPECT_EQ(read, file_size) << "Error reading persistent data file."; - EXPECT_TRUE(ParseDump(dump, &persistent_data_)); + + SavedStorage proto; + EXPECT_TRUE(proto.ParseFromString(dump)); + persistent_data_.insert(proto.files().begin(), proto.files().end()); } TestSleep::SyncFakeClock(); } @@ -231,7 +63,13 @@ void RebootTest::TearDown() { auto file = file_system_->Open(persistent_data_filename_, FileSystem::kCreate | FileSystem::kTruncate); ASSERT_TRUE(file) << "Failed to open file: " << persistent_data_filename_; - std::string dump = DumpData(persistent_data_); + + SavedStorage proto; + proto.mutable_files()->insert(persistent_data_.begin(), + persistent_data_.end()); + std::string dump; + ASSERT_TRUE(proto.SerializeToString(&dump)); + const ssize_t bytes_written = file->Write(dump.data(), dump.length()); EXPECT_EQ(bytes_written, static_cast(dump.length())); WvCdmTestBase::TearDown(); @@ -254,41 +92,6 @@ void RebootTest::SaveTime(const std::string& key, int64_t time) { persistent_data_[key] = std::to_string(time); } -/** Test the dump and restore functions above. This does not test CDM - functionality. */ -TEST_F(RebootTest, TestDumpUtil) { - // Check that an empty map can be saved. - std::map map1; - const std::string dump = DumpData(map1); - std::map map2; - EXPECT_TRUE(ParseDump(dump, &map2)); - EXPECT_EQ(map1, map2); - // Now fill it with some data and try again. - map1["key1"] = "this is a string. "; - map1["key2"] = "mismatch } {"; - map1["key3"] = "mismatch } "; - map1["key4"] = "mismatch {"; - map1["key5"] = "this: { has { matched } } braces { /.,)(**&^$&^% }"; - map1["key6"] = ""; - map1["00 whitespace in key 00"] = "value is ok"; - // This key looks like it might be hex. It should show up as hex in the - // save file. - map1["0x_bad_key_00"] = "value is ok"; - std::string big_string = "start with something {binary"; - // Double big_string 8 times, i.e. times 256, so it's bigger than 2k: - for (int i = 0; i < 8; i++) big_string = big_string + big_string; - map1["big_file"] = big_string; - const std::string dump2 = DumpData(map1); - std::map map3; - EXPECT_TRUE(ParseDump(dump2, &map3)); - EXPECT_EQ(map1, map3); - if (test_pass() == 0) { - persistent_data_ = map1; - } else { - EXPECT_EQ(persistent_data_, map1); - } -} - /** Verify that the file system stores files from one test pass to the next. */ TEST_F(RebootTest, FilesArePersistent) { const std::string key = "saved_value"; diff --git a/libwvdrmengine/cdm/core/test/reboot_test.h b/libwvdrmengine/cdm/core/test/reboot_test.h index fae4993e..5d9b097e 100644 --- a/libwvdrmengine/cdm/core/test/reboot_test.h +++ b/libwvdrmengine/cdm/core/test/reboot_test.h @@ -22,17 +22,6 @@ class RebootTest : public WvCdmTestBaseWithEngine { static void set_file_system(wvutil::FileSystem* file_system) { file_system_ = file_system; } - // Dump a map to a std string in an almost human readable way so that the map - // can be rebuilt using ParseDump below. The keys in the map must be standard - // identifier strings, which means no special characters or whitespace. By - // "almost human readable", we mean that a human debugging the dump will be - // able to find the keys, and see the values if they are printable or see a - // hex dump of the values if they are not. - static std::string DumpData(const std::map& data); - // Parse a dump generated by DumpData and recreate the original data map. - // Returns true on success. - static bool ParseDump(const std::string& dump, - std::map* data); static int test_pass() { return default_config_->test_pass(); } diff --git a/libwvdrmengine/oemcrypto/odk/include/core_message_features.h b/libwvdrmengine/oemcrypto/odk/include/core_message_features.h index ea689076..e4d6a0e3 100644 --- a/libwvdrmengine/oemcrypto/odk/include/core_message_features.h +++ b/libwvdrmengine/oemcrypto/odk/include/core_message_features.h @@ -26,9 +26,9 @@ struct CoreMessageFeatures { // This is the published version of the ODK Core Message library. The default // behavior is for the server to restrict messages to at most this version - // number. The default is 18.4. - uint32_t maximum_major_version = 18; - uint32_t maximum_minor_version = 4; + // number. The default is 19.0. + uint32_t maximum_major_version = 19; + uint32_t maximum_minor_version = 0; bool operator==(const CoreMessageFeatures &other) const; bool operator!=(const CoreMessageFeatures &other) const { diff --git a/libwvdrmengine/oemcrypto/odk/include/odk_structs.h b/libwvdrmengine/oemcrypto/odk/include/odk_structs.h index 99cc9f09..c0989277 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-10" +#define ODK_RELEASE_DATE "ODK v19.0 2024-02-23" /* The lowest version number for an ODK message. */ #define ODK_FIRST_VERSION 16 diff --git a/libwvdrmengine/oemcrypto/odk/src/odk_timer.c b/libwvdrmengine/oemcrypto/odk/src/odk_timer.c index c837d783..57e4f431 100644 --- a/libwvdrmengine/oemcrypto/odk/src/odk_timer.c +++ b/libwvdrmengine/oemcrypto/odk/src/odk_timer.c @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC. All rights reserved. This file and proprietary +// Copyright 2019 Google LLC. This file and proprietary // source code may only be used and distributed under the Widevine // License Agreement. diff --git a/libwvdrmengine/oemcrypto/odk/test/odk_test.cpp b/libwvdrmengine/oemcrypto/odk/test/odk_test.cpp index 955741ca..41996d9f 100644 --- a/libwvdrmengine/oemcrypto/odk/test/odk_test.cpp +++ b/libwvdrmengine/oemcrypto/odk/test/odk_test.cpp @@ -1292,7 +1292,8 @@ std::vector TestCases() { {0, 16, 5, 16, 5}, {0, 17, 1, 17, 1}, {0, 17, 2, 17, 2}, - {0, 18, 4, 18, 4}, // Change to 19 when the default version is updated. + {0, 18, 3, 18, 3}, // Change to 19 when the default version is updated. + {0, 18, 4, 18, 4}, }; return test_cases; } diff --git a/libwvdrmengine/oemcrypto/test/oec_device_features.cpp b/libwvdrmengine/oemcrypto/test/oec_device_features.cpp index 5047a39e..0bd759f6 100644 --- a/libwvdrmengine/oemcrypto/test/oec_device_features.cpp +++ b/libwvdrmengine/oemcrypto/test/oec_device_features.cpp @@ -151,6 +151,7 @@ void DeviceFeatures::PickDerivedKey() { derive_key_method = TEST_PROVISION_30; return; case OEMCrypto_DrmCertificate: + case OEMCrypto_DrmReprovisioning: if (OEMCrypto_ERROR_NOT_IMPLEMENTED != OEMCrypto_LoadTestRSAKey()) { derive_key_method = LOAD_TEST_RSA_KEY; } @@ -237,6 +238,8 @@ const char* ProvisioningMethodName(OEMCrypto_ProvisioningMethod method) { return "OEMCrypto_OEMCertificate"; case OEMCrypto_BootCertificateChain: return "OEMCrypto_BootCertificateChain"; + case OEMCrypto_DrmReprovisioning: + return "OEMCrypto_DrmReprovisioning"; } // Not reachable return ""; diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_cast_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_cast_test.cpp index 34c39319..2a6e0197 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_cast_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_cast_test.cpp @@ -11,7 +11,7 @@ using ::testing::Range; namespace wvoec { -/// @addtogroup generic +/// @addtogroup cast /// @{ /** If a device can load a private key with the alternate padding schemes, it @@ -82,10 +82,7 @@ TEST_F(OEMCryptoLoadsCertificateAlternates, ForbidPrepAndSign) { OEMCryptoResult result = OEMCrypto_PrepAndSignLicenseRequest( s.session_id(), message.data(), message.size(), &core_message_length, signature.data(), &signature_length); - // TODO: remove OEMCrypto_ERROR_INVALID_RSA_KEY once OEMCrypto v16 is not - // supported anymore. This error code has been deprecated since v17. - ASSERT_TRUE(result == OEMCrypto_ERROR_INVALID_KEY || - result == OEMCrypto_ERROR_INVALID_RSA_KEY); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_KEY, result); const vector zero(signature.size(), 0); ASSERT_EQ(signature, zero); // Signature should not have been computed. }