Update VMP/RA Tests

Before the VMP/RA tests only tested that decryption was successful
(checking the return code) but did not test the actual success of the
decryption (checking the decrypted plaintext against golden
plaintext).

This brings this repo in sync with the internal repo's commit
58d85cf6b19ecfb932f8edc2eaa8e907a1d21489.
This commit is contained in:
Aaron Vaage
2021-02-17 11:07:18 -08:00
parent 8a3cbb14c0
commit cff64dd7df
10 changed files with 503 additions and 211 deletions

View File

@@ -1,172 +0,0 @@
---
Language: Cpp
# BasedOnStyle: Chromium
AccessModifierOffset: -1
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
SortPriority: 0
- Regex: '^<.*\.h>'
Priority: 1
SortPriority: 0
- Regex: '^<.*'
Priority: 2
SortPriority: 0
- Regex: '.*'
Priority: 3
SortPriority: 0
IncludeIsMainRegex: '([-_](test|unittest))?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: true
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
CanonicalDelimiter: ''
BasedOnStyle: google
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Auto
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
...

View File

@@ -1,9 +0,0 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.c text
*.cc text
*.h text
*.txt text

1
whitebox/.gitignore vendored
View File

@@ -1 +0,0 @@
bazel-*

View File

@@ -65,7 +65,7 @@ http_archive(
new_git_repository(
name = "odk_repo",
build_file = "//external:odk.BUILD",
commit = "565237f8e6900e467eb236040374428387e90bd0",
commit = "c1401c6a1cc6a4378b6aa3d1c3d3f1f58278616e",
remote = "https://widevine-partner.googlesource.com/oemcrypto_core_message.git",
)

View File

@@ -130,7 +130,6 @@ cc_library(
name = "license_whitebox_test",
testonly = True,
srcs = [
"license_whitebox_chromeos_test.cc",
"license_whitebox_create_test.cc",
"license_whitebox_decrypt_test.cc",
"license_whitebox_get_secret_string_test.cc",
@@ -143,6 +142,7 @@ cc_library(
"license_whitebox_sign_renewal_request_test.cc",
"license_whitebox_test_base.cc",
"license_whitebox_verify_renewal_response_test.cc",
"remote_attestation_and_verification_test.cc",
],
hdrs = [
"license_whitebox_test_base.h",

View File

@@ -10,6 +10,7 @@
#include "api/test_license_builder.h"
#include "crypto_utils/crypto_util.h"
#include "crypto_utils/rsa_key.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace widevine {
@@ -130,14 +131,18 @@ TEST_F(LicenseWhiteboxProcessLicenseResponseErrorTest,
InvalidSignatureForModifedMessage) {
Modify(&license_.message);
ASSERT_EQ(
WB_License_ProcessLicenseResponse(
whitebox_, license_.core_message.data(), license_.core_message.size(),
license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
license_.request.data(), license_.request.size()),
WB_RESULT_INVALID_SIGNATURE);
WB_Result result = WB_License_ProcessLicenseResponse(
whitebox_, license_.core_message.data(), license_.core_message.size(),
license_.message.data(), license_.message.size(),
license_.signature.data(), license_.signature.size(),
license_.session_key.data(), license_.session_key.size(),
license_.request.data(), license_.request.size());
// Depending on where/how the message is verified, an implementation can
// return invalid parameter or invalid signature. Preferably it would be
// "invalid signature", but not required.
ASSERT_THAT(result, testing::AnyOf(WB_RESULT_INVALID_PARAMETER,
WB_RESULT_INVALID_SIGNATURE));
}
TEST_F(LicenseWhiteboxProcessLicenseResponseErrorTest,

View File

@@ -0,0 +1,457 @@
// Copyright 2020 Google LLC. All Rights Reserved.
#include "api/license_whitebox.h"
#include <vector>
#include "api/golden_data.h"
#include "api/license_whitebox_test_base.h"
#include "api/result.h"
#include "api/test_license_builder.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace widevine {
namespace {
using RemoteAttestation = TestLicenseBuilder::RemoteAttestation;
using VerificationStatus = TestLicenseBuilder::VerificationStatus;
// We can't use the actual keys with TEST_P, so define an enum that we can use
// to communicate which key to use.
enum class Key {
kCrypto,
kDecode,
kHardware,
};
// Mode will communicate which type of decryption we want to use (decrypt or
// masked decrypt) and what the expected result should be (successful
// decryption or unsuccessful decryption).
enum class Mode {
kDecryptPass,
kDecryptFail,
kMaskedDecryptPass,
kMaskedDecryptFail,
};
} // namespace
class RemoteAttestationAndVerificationTest
: public LicenseWhiteboxTestBase,
public testing::WithParamInterface<
std::tuple<Key, RemoteAttestation, VerificationStatus, Mode>> {
protected:
void SetUp() override {
LicenseWhiteboxTestBase::SetUp();
Key key;
std::tie(key, ra_, vmp_, mode_) = GetParam();
switch (key) {
case Key::kCrypto:
key_ = golden_data_.CBCCryptoKey();
break;
case Key::kDecode:
key_ = golden_data_.CBCDecodeKey();
break;
case Key::kHardware:
key_ = golden_data_.CBCHardwareKey();
break;
}
}
WB_Result LoadLicense(const GoldenData::Key& key,
RemoteAttestation remote_attestation,
VerificationStatus verification_status) {
TestLicenseBuilder builder;
builder.AddContentKey(key.level, key.id, key.content->key);
builder.GetSettings().remote_attestation = remote_attestation;
builder.GetSettings().verification_status = verification_status;
License license;
builder.Build(*public_key_, &license);
return WB_License_ProcessLicenseResponse(
whitebox_, license.core_message.data(), license.core_message.size(),
license.message.data(), license.message.size(),
license.signature.data(), license.signature.size(),
license.session_key.data(), license.session_key.size(),
license.request.data(), license.request.size());
}
WB_Result Decrypt(const GoldenData::Key& key) {
size_t plaintext_size = key.content->ciphertext.size();
plaintext_.resize(plaintext_size);
auto result = WB_License_Decrypt(
whitebox_, WB_CIPHER_MODE_CBC, key.id.data(), key.id.size(),
key.content->ciphertext.data(), key.content->ciphertext.size(),
key.content->iv.data(), key.content->iv.size(), plaintext_.data(),
&plaintext_size);
plaintext_.resize(plaintext_size);
return result;
}
WB_Result MaskedDecrypt(const GoldenData::Key& key) {
size_t masked_text_size = key.content->ciphertext.size();
std::vector<uint8_t> masked_text(masked_text_size);
auto result = WB_License_MaskedDecrypt(
whitebox_, WB_CIPHER_MODE_CBC, key.id.data(), key.id.size(),
key.content->ciphertext.data(), key.content->ciphertext.size(),
key.content->iv.data(), key.content->iv.size(), masked_text.data(),
&masked_text_size);
masked_text.resize(masked_text_size);
if (result != WB_RESULT_OK) {
return result;
}
// The secret string size is implementation specific, so we just use a
// size that should be "big enough". If it is ever too small, we can just
// increase the size.
size_t secret_string_size = 256;
std::vector<uint8_t> secret_string(secret_string_size);
result = WB_License_GetSecretString(
whitebox_, WB_CIPHER_MODE_CBC, key.id.data(), key.id.size(),
secret_string.data(), &secret_string_size);
secret_string.resize(secret_string_size);
if (result != WB_RESULT_OK) {
return result;
}
plaintext_.resize(masked_text_size);
WB_License_Unmask(masked_text.data(), 0, masked_text.size(),
secret_string.data(), secret_string.size(),
plaintext_.data());
return result;
}
GoldenData::Key key_;
RemoteAttestation ra_;
VerificationStatus vmp_;
Mode mode_;
// This is the buffer used to store the output of each decrypt and unmask
// call.
std::vector<uint8_t> plaintext_;
};
TEST_P(RemoteAttestationAndVerificationTest, Decrypt) {
ASSERT_EQ(LoadLicense(key_, ra_, vmp_), WB_RESULT_OK);
switch (mode_) {
case Mode::kDecryptPass:
ASSERT_EQ(Decrypt(key_), WB_RESULT_OK);
ASSERT_EQ(plaintext_, key_.content->plaintext);
break;
case Mode::kDecryptFail:
ASSERT_NE(Decrypt(key_), WB_RESULT_OK);
break;
case Mode::kMaskedDecryptPass:
ASSERT_EQ(MaskedDecrypt(key_), WB_RESULT_OK);
ASSERT_EQ(plaintext_, key_.content->plaintext);
break;
case Mode::kMaskedDecryptFail:
ASSERT_NE(MaskedDecrypt(key_), WB_RESULT_OK);
break;
}
}
// We use "remote_attestation_verified" and "platform_verification_status" to
// determine whether the platform is hardware verified.
//
// Each variable can be in one of three states. Each variable has a missing
// value, a true value, and a false value.
//
// |----------------------------------------------------------|
// | | RA N/A | RA VERIFIED | RA NOT VERIFIED |
// |----------------------------------------------------------|
// | VMP N/A | 0 | 1 | 0 |
// | VMP HW_VERIFIED | 1 | 1 | 0 |
// | VMP OTHER | 0 | 0 | 0 |
// |----------------------------------------------------------|
INSTANTIATE_TEST_SUITE_P(NoRemoteAttestationNoVerification,
RemoteAttestationAndVerificationTest,
::testing::Values(
// Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kUnavailable,
VerificationStatus::kUnavailable,
Mode::kDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kUnavailable,
VerificationStatus::kUnavailable,
Mode::kDecryptFail),
std::make_tuple(Key::kHardware,
RemoteAttestation::kUnavailable,
VerificationStatus::kUnavailable,
Mode::kDecryptFail),
// Masked Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kUnavailable,
VerificationStatus::kUnavailable,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kUnavailable,
VerificationStatus::kUnavailable,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kHardware,
RemoteAttestation::kUnavailable,
VerificationStatus::kUnavailable,
Mode::kMaskedDecryptFail)));
INSTANTIATE_TEST_SUITE_P(UnverifiedRemoteAttestationNoVerification,
RemoteAttestationAndVerificationTest,
::testing::Values(
// Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kUnverified,
VerificationStatus::kUnavailable,
Mode::kDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kUnverified,
VerificationStatus::kUnavailable,
Mode::kDecryptFail),
std::make_tuple(Key::kHardware,
RemoteAttestation::kUnverified,
VerificationStatus::kUnavailable,
Mode::kDecryptFail),
// Masked Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kUnverified,
VerificationStatus::kUnavailable,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kUnverified,
VerificationStatus::kUnavailable,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kHardware,
RemoteAttestation::kUnverified,
VerificationStatus::kUnavailable,
Mode::kMaskedDecryptFail)));
INSTANTIATE_TEST_SUITE_P(VerifiedRemoteAttestationNoVerification,
RemoteAttestationAndVerificationTest,
::testing::Values(
// Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kVerified,
VerificationStatus::kUnavailable,
Mode::kDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kVerified,
VerificationStatus::kUnavailable,
Mode::kDecryptPass),
std::make_tuple(Key::kHardware,
RemoteAttestation::kVerified,
VerificationStatus::kUnavailable,
Mode::kDecryptPass),
// Masked Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kVerified,
VerificationStatus::kUnavailable,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kVerified,
VerificationStatus::kUnavailable,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kHardware,
RemoteAttestation::kVerified,
VerificationStatus::kUnavailable,
Mode::kMaskedDecryptPass)));
INSTANTIATE_TEST_SUITE_P(
NoRemoteAttestationHardwareVerification,
RemoteAttestationAndVerificationTest,
::testing::Values(
// Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kUnavailable,
VerificationStatus::kHardwareVerified,
Mode::kDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kUnavailable,
VerificationStatus::kHardwareVerified,
Mode::kDecryptPass),
std::make_tuple(Key::kHardware,
RemoteAttestation::kUnavailable,
VerificationStatus::kHardwareVerified,
Mode::kDecryptPass),
// Masked Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kUnavailable,
VerificationStatus::kHardwareVerified,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kUnavailable,
VerificationStatus::kHardwareVerified,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kHardware,
RemoteAttestation::kUnavailable,
VerificationStatus::kHardwareVerified,
Mode::kMaskedDecryptPass)));
INSTANTIATE_TEST_SUITE_P(
UnverifiedRemoteAttestationHardwareVerification,
RemoteAttestationAndVerificationTest,
::testing::Values(
// Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kUnverified,
VerificationStatus::kHardwareVerified,
Mode::kDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kUnverified,
VerificationStatus::kHardwareVerified,
Mode::kDecryptFail),
std::make_tuple(Key::kHardware,
RemoteAttestation::kUnverified,
VerificationStatus::kHardwareVerified,
Mode::kDecryptFail),
// Masked Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kUnverified,
VerificationStatus::kHardwareVerified,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kUnverified,
VerificationStatus::kHardwareVerified,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kHardware,
RemoteAttestation::kUnverified,
VerificationStatus::kHardwareVerified,
Mode::kMaskedDecryptFail)));
INSTANTIATE_TEST_SUITE_P(
VerifiedRemoteAttestationHardwareVerification,
RemoteAttestationAndVerificationTest,
::testing::Values(
// Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kVerified,
VerificationStatus::kHardwareVerified,
Mode::kDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kVerified,
VerificationStatus::kHardwareVerified,
Mode::kDecryptPass),
std::make_tuple(Key::kHardware,
RemoteAttestation::kVerified,
VerificationStatus::kHardwareVerified,
Mode::kDecryptPass),
// Masked Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kVerified,
VerificationStatus::kHardwareVerified,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kVerified,
VerificationStatus::kHardwareVerified,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kHardware,
RemoteAttestation::kVerified,
VerificationStatus::kHardwareVerified,
Mode::kMaskedDecryptPass)));
INSTANTIATE_TEST_SUITE_P(NoRemoteAttestationOtherVerification,
RemoteAttestationAndVerificationTest,
::testing::Values(
// Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kUnavailable,
VerificationStatus::kOther,
Mode::kDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kUnavailable,
VerificationStatus::kOther,
Mode::kDecryptFail),
std::make_tuple(Key::kHardware,
RemoteAttestation::kUnavailable,
VerificationStatus::kOther,
Mode::kDecryptFail),
// Masked Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kUnavailable,
VerificationStatus::kOther,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kUnavailable,
VerificationStatus::kOther,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kHardware,
RemoteAttestation::kUnavailable,
VerificationStatus::kOther,
Mode::kMaskedDecryptFail)));
INSTANTIATE_TEST_SUITE_P(UnverifiedRemoteAttestationOtherVerification,
RemoteAttestationAndVerificationTest,
::testing::Values(
// Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kUnverified,
VerificationStatus::kOther,
Mode::kDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kUnverified,
VerificationStatus::kOther,
Mode::kDecryptFail),
std::make_tuple(Key::kHardware,
RemoteAttestation::kUnverified,
VerificationStatus::kOther,
Mode::kDecryptFail),
// Masked Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kUnverified,
VerificationStatus::kOther,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kUnverified,
VerificationStatus::kOther,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kHardware,
RemoteAttestation::kUnverified,
VerificationStatus::kOther,
Mode::kMaskedDecryptFail)));
INSTANTIATE_TEST_SUITE_P(VerifiedRemoteAttestationOtherVerification,
RemoteAttestationAndVerificationTest,
::testing::Values(
// Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kVerified,
VerificationStatus::kOther,
Mode::kDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kVerified,
VerificationStatus::kOther,
Mode::kDecryptFail),
std::make_tuple(Key::kHardware,
RemoteAttestation::kVerified,
VerificationStatus::kOther,
Mode::kDecryptFail),
// Masked Decrypt
std::make_tuple(Key::kCrypto,
RemoteAttestation::kVerified,
VerificationStatus::kOther,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kDecode,
RemoteAttestation::kVerified,
VerificationStatus::kOther,
Mode::kMaskedDecryptPass),
std::make_tuple(Key::kHardware,
RemoteAttestation::kVerified,
VerificationStatus::kOther,
Mode::kMaskedDecryptFail)));
} // namespace widevine

View File

@@ -4,6 +4,7 @@ cc_library(
name = "gmock",
hdrs = [
"gmock.h",
"gmock-matchers.h",
],
include_prefix = "testing/gmock/include/gmock/",
strip_include_prefix = "//chromium_deps/testing/include/gmock/",

View File

@@ -0,0 +1,8 @@
// Copyright 2020 Google LLC. All Rights Reserved.
#ifndef TESTING_GMOCK_MATCHERS_INCLUDE_GMOCK_MATCHERS_H_
#define TESTING_GMOCK_MATCHERS_INCLUDE_GMOCK_MATCHERS_H_
#include "gmock/gmock-matchers.h"
#endif // TESTING_GMOCK_MATCHERS_INCLUDE_GMOCK_MATCHERS_H_

View File

@@ -326,30 +326,33 @@ WB_Result DecryptBuffer(WB_CipherMode mode,
// | VMP OTHER | 0 | 0 | 0 |
// |----------------------------------------------------------|
bool IsPlatformHardwareVerified(const video_widevine::License& license) {
const bool has_ra = license.has_remote_attestation_verified();
const bool has_vmp = license.has_platform_verification_status();
if (!has_ra && !has_vmp) {
return false;
int ra;
if (!license.has_remote_attestation_verified()) {
ra = 0;
} else if (license.remote_attestation_verified()) {
ra = 1;
} else {
ra = 2;
}
// We trust "missing" more than "false". Now that we know we have some values,
// default to "it's okay" and only override it if we have a new value from the
// license.
bool flags[2] = {true, true};
if (has_ra) {
flags[0] = license.remote_attestation_verified();
int vmp;
if (!license.has_platform_verification_status()) {
vmp = 0;
} else if (license.platform_verification_status() ==
video_widevine::PLATFORM_HARDWARE_VERIFIED) {
vmp = 1;
} else {
vmp = 2;
}
if (has_vmp) {
flags[1] = license.platform_verification_status() ==
video_widevine::PLATFORM_HARDWARE_VERIFIED;
}
// Use int to match the table we have in the comment above.
const int table[3][3] = {
{0, 1, 0},
{1, 1, 0},
{0, 0, 0},
};
// If we were missing a value, that flag will still be true. But if we see any
// false values, then we know something was found to be invalid.
return flags[0] && flags[1];
return table[vmp][ra] == 1;
}
} // namespace