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:
@@ -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
|
||||
...
|
||||
|
||||
9
whitebox/.gitattributes
vendored
9
whitebox/.gitattributes
vendored
@@ -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
1
whitebox/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
bazel-*
|
||||
@@ -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",
|
||||
)
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
|
||||
457
whitebox/api/remote_attestation_and_verification_test.cc
Normal file
457
whitebox/api/remote_attestation_and_verification_test.cc
Normal 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
|
||||
@@ -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/",
|
||||
|
||||
@@ -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_
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user