chromium/media/cdm/aes_decryptor_unittest.cc

// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "media/cdm/aes_decryptor.h"

#include <stdint.h>

#include <memory>
#include <set>
#include <string>
#include <vector>

#include "base/containers/to_vector.h"
#include "base/debug/leak_annotations.h"
#include "base/functional/bind.h"
#include "base/json/json_reader.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/values.h"
#include "media/base/cdm_callback_promise.h"
#include "media/base/cdm_config.h"
#include "media/base/cdm_key_information.h"
#include "media/base/decoder_buffer.h"
#include "media/base/decrypt_config.h"
#include "media/base/decryptor.h"
#include "media/base/media_switches.h"
#include "media/base/mock_filters.h"
#include "media/media_buildflags.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest-param-test.h"
#include "testing/gtest/include/gtest/gtest.h"

#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
// GN check does not understand conditionals. Android & Fuchsia need nogncheck.
#include "media/cdm/api/content_decryption_module.h"  // nogncheck
#include "media/cdm/cdm_adapter.h"
#include "media/cdm/cdm_auxiliary_helper.h"
#include "media/cdm/cdm_module.h"
#include "media/cdm/external_clear_key_test_helper.h"
#include "media/cdm/mock_helpers.h"
#include "media/cdm/simple_cdm_allocator.h"
#endif

_;
AtMost;
Gt;
IsNull;
NotNull;
SaveArg;
StrictMock;
StrNe;
Unused;

MATCHER(IsEmpty, "") {}
MATCHER(NotEmpty, "") {}
MATCHER(IsJSONDictionary, "") {}
MATCHER(IsNullTime, "") {}

namespace media {

namespace {

const uint8_t kOriginalData[] =;
const int kOriginalDataSize =;

// In the examples below, 'k'(key) has to be 16 bytes, and will always require
// 2 bytes of padding. 'kid'(keyid) is variable length, and may require 0, 1,
// or 2 bytes of padding.

const uint8_t kKeyId[] =;

// Key is 0x0405060708090a0b0c0d0e0f10111213,
// base64 equivalent is BAUGBwgJCgsMDQ4PEBESEw.
const char kKeyAsJWK[] =;

// Same kid as kKeyAsJWK, key to decrypt kEncryptedData2
const char kKeyAlternateAsJWK[] =;

const char kWrongKeyAsJWK[] =;

const char kWrongSizedKeyAsJWK[] =;

const uint8_t kIv[] =;

// kOriginalData encrypted with kKey and kIv but without any subsamples (or
// equivalently using kSubsampleEntriesCypherOnly).
const uint8_t kEncryptedData[] =;

// kOriginalData encrypted with kSubsampleKey and kSubsampleIv using
// kSubsampleEntriesNormal.
const uint8_t kSubsampleEncryptedData[] =;

const uint8_t kOriginalData2[] =;

const uint8_t kIv2[] =;

const uint8_t kKeyId2[] =;

const char kKey2AsJWK[] =;

// 'k' in bytes is x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20x21x22x23

const uint8_t kEncryptedData2[] =;

// Subsample entries for testing. The sum of |cypher_bytes| and |clear_bytes| of
// all entries must be equal to kOriginalDataSize to make the subsample entries
// valid.

const SubsampleEntry kSubsampleEntriesNormal[] =;

const SubsampleEntry kSubsampleEntriesWrongSize[] =;

const SubsampleEntry kSubsampleEntriesInvalidTotalSize[] =;

const SubsampleEntry kSubsampleEntriesClearOnly[] =;

const SubsampleEntry kSubsampleEntriesCypherOnly[] =;

scoped_refptr<DecoderBuffer> CreateEncryptedBuffer(
    const std::vector<uint8_t>& data,
    const std::vector<uint8_t>& key_id,
    const std::vector<uint8_t>& iv,
    const std::vector<SubsampleEntry>& subsample_entries) {}

scoped_refptr<DecoderBuffer> CreateClearBuffer(
    const std::vector<uint8_t>& data) {}

enum ExpectedResult {};

enum class TestType {};

}  // namespace

// These tests only test decryption logic (no decoding).
class AesDecryptorTest : public testing::TestWithParam<TestType> {};

TEST_P(AesDecryptorTest, CreateSessionWithEmptyInitData) {}

TEST_P(AesDecryptorTest, CreateSessionWithVariousLengthInitData_WebM) {}

TEST_P(AesDecryptorTest, MultipleCreateSession) {}

TEST_P(AesDecryptorTest, CreateSessionWithCencInitData) {}

TEST_P(AesDecryptorTest, CreateSessionWithKeyIdsInitData) {}

TEST_P(AesDecryptorTest, NormalDecryption) {}

TEST_P(AesDecryptorTest, UnencryptedFrame) {}

TEST_P(AesDecryptorTest, WrongKey) {}

TEST_P(AesDecryptorTest, NoKey) {}

TEST_P(AesDecryptorTest, KeyReplacement) {}

TEST_P(AesDecryptorTest, WrongSizedKey) {}

TEST_P(AesDecryptorTest, MultipleKeysAndFrames) {}

TEST_P(AesDecryptorTest, CorruptedIv) {}

TEST_P(AesDecryptorTest, CorruptedData) {}

TEST_P(AesDecryptorTest, EncryptedAsUnencryptedFailure) {}

TEST_P(AesDecryptorTest, SubsampleDecryption) {}

// Ensures noninterference of data offset and subsample mechanisms. We never
// expect to encounter this in the wild, but since the DecryptConfig doesn't
// disallow such a configuration, it should be covered.
TEST_P(AesDecryptorTest, SubsampleDecryptionWithOffset) {}

TEST_P(AesDecryptorTest, SubsampleWrongSize) {}

TEST_P(AesDecryptorTest, SubsampleInvalidTotalSize) {}

// No cypher bytes in any of the subsamples.
TEST_P(AesDecryptorTest, SubsampleClearBytesOnly) {}

// No clear bytes in any of the subsamples.
TEST_P(AesDecryptorTest, SubsampleCypherBytesOnly) {}

TEST_P(AesDecryptorTest, CloseSession) {}

TEST_P(AesDecryptorTest, RemoveSession) {}

TEST_P(AesDecryptorTest, RemoveThenCloseSession) {}

TEST_P(AesDecryptorTest, NoKeyAfterCloseSession) {}

TEST_P(AesDecryptorTest, LatestKeyUsed) {}

TEST_P(AesDecryptorTest, LatestKeyUsedAfterCloseSession) {}

TEST_P(AesDecryptorTest, JWKKey) {}

TEST_P(AesDecryptorTest, GetKeyIds) {}

TEST_P(AesDecryptorTest, NoKeysChangeForSameKey) {}

TEST_P(AesDecryptorTest, RandomSessionIDs) {}

INSTANTIATE_TEST_SUITE_P();

#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
INSTANTIATE_TEST_SUITE_P();
#endif

// TODO(jrummell): Once MojoCdm/MojoCdmService/MojoDecryptor/
// MojoDecryptorService are implemented, add a third version that tests the
// CDM via mojo.

}  // namespace media