From 80fedfcd2fbfc00c23773d8f1ff8422a0cb1618a Mon Sep 17 00:00:00 2001 From: Cong Lin Date: Mon, 26 Aug 2024 15:50:33 -0700 Subject: [PATCH] Fix test message format for cast receiver Merge of https://widevine-internal-review.git.corp.google.com/c/cdm/+/206071 Message to be signed by CAST funciton is supposed to be in a certain format: "constant prefix + SHA1(message)". Some of our current CAST tests uses random message which break this specification. This fixes the input message. Test: Cast tests with run_fake_l1_tests Bug: 359893908 Change-Id: I6b318d749971d837f13daa7b147313e8e0b1d3d0 --- .../oemcrypto/test/oemcrypto_cast_test.cpp | 16 ++-------- .../oemcrypto/test/oemcrypto_cast_test.h | 32 ++++++++++++++++--- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_cast_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_cast_test.cpp index 91730253..85a2005b 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_cast_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_cast_test.cpp @@ -5,8 +5,6 @@ #include "oemcrypto_cast_test.h" -#include "oemcrypto_usage_table_test.h" - using ::testing::Range; namespace wvoec { @@ -262,18 +260,8 @@ class OEMCryptoCastReceiverTest : public OEMCryptoLoadsCertificateAlternates { ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_)); - // The application will compute the SHA-1 Hash of the message, so this - // test must do that also. - uint8_t hash[SHA_DIGEST_LENGTH]; - if (!SHA1(message.data(), message.size(), hash)) { - dump_boringssl_error(); - FAIL() << "boringssl error creating SHA1 hash."; - } - - // The application will prepend the digest info to the hash. - // SHA-1 digest info prefix = 0x30 0x21 0x30 ... - vector digest = wvutil::a2b_hex("3021300906052b0e03021a05000414"); - digest.insert(digest.end(), hash, hash + SHA_DIGEST_LENGTH); + vector digest; + ASSERT_NO_FATAL_FAILURE(PrepareCastDigestedMessage(message, digest)); // OEMCrypto will apply the padding, and encrypt to generate the // signature. diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_cast_test.h b/libwvdrmengine/oemcrypto/test/oemcrypto_cast_test.h index c812ebea..0efc8ee3 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_cast_test.h +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_cast_test.h @@ -14,6 +14,7 @@ #include "OEMCryptoCENC.h" #include "oemcrypto_provisioning_test.h" #include "oemcrypto_session_tests_helper.h" +#include "oemcrypto_usage_table_test.h" namespace wvoec { @@ -25,6 +26,26 @@ std::string MaybeHex(const std::vector& data); // This test attempts to use alternate algorithms for loaded device certs. class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate { protected: + // The message to be signed by OEMCrypto_GenerateRSASignature() starts with a + // constant digest info prefix followed by a SHA-1 hash of the message. + void PrepareCastDigestedMessage(const std::vector& message, + std::vector& digested_message) { + // The application will compute the SHA-1 Hash of the message, so this + // test must do that also. + uint8_t hash[SHA_DIGEST_LENGTH]; + if (!SHA1(message.data(), message.size(), hash)) { + dump_boringssl_error(); + FAIL() << "boringssl error creating SHA1 hash."; + } + // The application will prepend the digest info to the hash. + // SHA-1 digest info prefix = 0x30 0x21 0x30 ... + vector digest = wvutil::a2b_hex("3021300906052b0e03021a05000414"); + digested_message.insert(digested_message.end(), digest.begin(), + digest.end()); + digested_message.insert(digested_message.end(), hash, + hash + SHA_DIGEST_LENGTH); + } + void TestSignature(RSA_Padding_Scheme scheme, size_t size) { Session s; ASSERT_NO_FATAL_FAILURE(s.open()); @@ -32,16 +53,19 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate { vector licenseRequest(size); GetRandBytes(licenseRequest.data(), licenseRequest.size()); + vector digested_message; + ASSERT_NO_FATAL_FAILURE( + PrepareCastDigestedMessage(licenseRequest, digested_message)); size_t signature_length = 0; OEMCryptoResult sts = OEMCrypto_GenerateRSASignature( - s.session_id(), licenseRequest.data(), licenseRequest.size(), nullptr, - &signature_length, scheme); + s.session_id(), digested_message.data(), digested_message.size(), + nullptr, &signature_length, scheme); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); ASSERT_NE(static_cast(0), signature_length); std::vector signature(signature_length, 0); sts = OEMCrypto_GenerateRSASignature( - s.session_id(), licenseRequest.data(), licenseRequest.size(), + s.session_id(), digested_message.data(), digested_message.size(), signature.data(), &signature_length, scheme); ASSERT_EQ(OEMCrypto_SUCCESS, sts) @@ -51,7 +75,7 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate { ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo( encoded_rsa_key_.data(), encoded_rsa_key_.size())); ASSERT_NO_FATAL_FAILURE(s.VerifyRsaSignature( - licenseRequest, signature.data(), signature_length, scheme)); + digested_message, signature.data(), signature_length, scheme)); } void DisallowDeriveKeys() {