#include "media/formats/webm/webm_crypto_helpers.h"
#include <array>
#include "base/containers/auto_spanification_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::ElementsAre;
namespace {
const auto kKeyId = std::to_array<uint8_t>({
0x01,
0x02,
0x03,
0x04,
0x05,
0x06,
0x07,
0x08,
});
}
namespace media {
TEST(WebMCryptoHelpersTest, EmptyData) {
std::unique_ptr<DecryptConfig> decrypt_config;
size_t data_offset;
ASSERT_FALSE(WebMCreateDecryptConfig(
nullptr, 0, kKeyId.data(), base::SpanificationSizeofForStdArray(kKeyId),
&decrypt_config, &data_offset));
}
TEST(WebMCryptoHelpersTest, ClearData) {
const uint8_t kData[] = {0x00, 0x0d, 0x0a, 0x0d, 0x0a};
std::unique_ptr<DecryptConfig> decrypt_config;
size_t data_offset;
ASSERT_TRUE(
WebMCreateDecryptConfig(kData, sizeof(kData), kKeyId.data(),
base::SpanificationSizeofForStdArray(kKeyId),
&decrypt_config, &data_offset));
EXPECT_EQ(1u, data_offset);
EXPECT_FALSE(decrypt_config);
}
TEST(WebMCryptoHelpersTest, EncryptedButNotEnoughBytes) {
const uint8_t kData[] = {0x01, 0x0d, 0x0a, 0x0d, 0x0a};
std::unique_ptr<DecryptConfig> decrypt_config;
size_t data_offset;
ASSERT_FALSE(
WebMCreateDecryptConfig(kData, sizeof(kData), kKeyId.data(),
base::SpanificationSizeofForStdArray(kKeyId),
&decrypt_config, &data_offset));
}
TEST(WebMCryptoHelpersTest, EncryptedNotPartitioned) {
const uint8_t kData[] = {
0x01,
0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a,
0x01, 0x02,
};
const auto kExpectedIv = std::to_array<uint8_t>({
0x0d,
0x0a,
0x0d,
0x0a,
0x0d,
0x0a,
0x0d,
0x0a,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
});
std::unique_ptr<DecryptConfig> decrypt_config;
size_t data_offset;
ASSERT_TRUE(
WebMCreateDecryptConfig(kData, sizeof(kData), kKeyId.data(),
base::SpanificationSizeofForStdArray(kKeyId),
&decrypt_config, &data_offset));
EXPECT_TRUE(decrypt_config);
EXPECT_EQ(
std::string(kKeyId.data(),
base::span(kKeyId)
.subspan(base::SpanificationSizeofForStdArray(kKeyId))
.data()),
decrypt_config->key_id());
EXPECT_EQ(std::string(
kExpectedIv.data(),
base::span(kExpectedIv)
.subspan(base::SpanificationSizeofForStdArray(kExpectedIv))
.data()),
decrypt_config->iv());
EXPECT_TRUE(decrypt_config->subsamples().empty());
}
TEST(WebMCryptoHelpersTest, EncryptedPartitionedMissingNumPartitionField) {
const uint8_t kData[] = {
0x03,
0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a,
};
std::unique_ptr<DecryptConfig> decrypt_config;
size_t data_offset;
ASSERT_FALSE(
WebMCreateDecryptConfig(kData, sizeof(kData), kKeyId.data(),
base::SpanificationSizeofForStdArray(kKeyId),
&decrypt_config, &data_offset));
}
TEST(WebMCryptoHelpersTest, EncryptedPartitionedNotEnoughBytesForOffsets) {
const uint8_t kData[] = {
0x03,
0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a,
0x02,
0x00, 0x00, 0x00, 0x03,
};
std::unique_ptr<DecryptConfig> decrypt_config;
size_t data_offset;
ASSERT_FALSE(
WebMCreateDecryptConfig(kData, sizeof(kData), kKeyId.data(),
base::SpanificationSizeofForStdArray(kKeyId),
&decrypt_config, &data_offset));
}
TEST(WebMCryptoHelpersTest, EncryptedPartitionedNotEnoughBytesForData) {
const uint8_t kData[] = {
0x03,
0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a,
0x02,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05,
0x00, 0x01, 0x02, 0x03,
};
std::unique_ptr<DecryptConfig> decrypt_config;
size_t data_offset;
ASSERT_FALSE(
WebMCreateDecryptConfig(kData, sizeof(kData), kKeyId.data(),
base::SpanificationSizeofForStdArray(kKeyId),
&decrypt_config, &data_offset));
}
TEST(WebMCryptoHelpersTest, EncryptedPartitionedNotEnoughBytesForData2) {
const uint8_t kData[] = {
0x03,
0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a,
0x02,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05,
0x00, 0x01, 0x02, 0x03, 0x04,
};
std::unique_ptr<DecryptConfig> decrypt_config;
size_t data_offset;
ASSERT_FALSE(
WebMCreateDecryptConfig(kData, sizeof(kData), kKeyId.data(),
base::SpanificationSizeofForStdArray(kKeyId),
&decrypt_config, &data_offset));
}
TEST(WebMCryptoHelpersTest, EncryptedPartitionedDecreasingOffsets) {
const uint8_t kData[] = {
0x03,
0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a,
0x02,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02,
0x00, 0x01, 0x02, 0x03, 0x04,
};
std::unique_ptr<DecryptConfig> decrypt_config;
size_t data_offset;
ASSERT_FALSE(
WebMCreateDecryptConfig(kData, sizeof(kData), kKeyId.data(),
base::SpanificationSizeofForStdArray(kKeyId),
&decrypt_config, &data_offset));
}
TEST(WebMCryptoHelpersTest, EncryptedPartitionedEvenNumberOfPartitions) {
const uint8_t kData[] = {
0x03,
0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a,
0x02,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
};
const auto kExpectedIv = std::to_array<uint8_t>({
0x0d,
0x0a,
0x0d,
0x0a,
0x0d,
0x0a,
0x0d,
0x0a,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
});
std::unique_ptr<DecryptConfig> decrypt_config;
size_t data_offset;
ASSERT_TRUE(
WebMCreateDecryptConfig(kData, sizeof(kData), kKeyId.data(),
base::SpanificationSizeofForStdArray(kKeyId),
&decrypt_config, &data_offset));
EXPECT_TRUE(decrypt_config);
EXPECT_EQ(
std::string(kKeyId.data(),
base::span(kKeyId)
.subspan(base::SpanificationSizeofForStdArray(kKeyId))
.data()),
decrypt_config->key_id());
EXPECT_EQ(std::string(
kExpectedIv.data(),
base::span(kExpectedIv)
.subspan(base::SpanificationSizeofForStdArray(kExpectedIv))
.data()),
decrypt_config->iv());
EXPECT_THAT(decrypt_config->subsamples(),
ElementsAre(SubsampleEntry(3, 2), SubsampleEntry(1, 0)));
EXPECT_EQ(18u, data_offset);
}
TEST(WebMCryptoHelpersTest, EncryptedPartitionedOddNumberOfPartitions) {
const uint8_t kData[] = {
0x03,
0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a,
0x01,
0x00, 0x00, 0x00, 0x03,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
};
const auto kExpectedIv = std::to_array<uint8_t>({
0x0d,
0x0a,
0x0d,
0x0a,
0x0d,
0x0a,
0x0d,
0x0a,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
});
std::unique_ptr<DecryptConfig> decrypt_config;
size_t data_offset;
ASSERT_TRUE(
WebMCreateDecryptConfig(kData, sizeof(kData), kKeyId.data(),
base::SpanificationSizeofForStdArray(kKeyId),
&decrypt_config, &data_offset));
EXPECT_TRUE(decrypt_config);
EXPECT_EQ(
std::string(kKeyId.data(),
base::span(kKeyId)
.subspan(base::SpanificationSizeofForStdArray(kKeyId))
.data()),
decrypt_config->key_id());
EXPECT_EQ(std::string(
kExpectedIv.data(),
base::span(kExpectedIv)
.subspan(base::SpanificationSizeofForStdArray(kExpectedIv))
.data()),
decrypt_config->iv());
EXPECT_THAT(decrypt_config->subsamples(), ElementsAre(SubsampleEntry(3, 3)));
EXPECT_EQ(14u, data_offset);
}
TEST(WebMCryptoHelpersTest, EncryptedPartitionedZeroNumberOfPartitions) {
const uint8_t kData[] = {
0x03,
0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a,
0x00,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
};
const auto kExpectedIv = std::to_array<uint8_t>({
0x0d,
0x0a,
0x0d,
0x0a,
0x0d,
0x0a,
0x0d,
0x0a,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
});
std::unique_ptr<DecryptConfig> decrypt_config;
size_t data_offset;
ASSERT_TRUE(
WebMCreateDecryptConfig(kData, sizeof(kData), kKeyId.data(),
base::SpanificationSizeofForStdArray(kKeyId),
&decrypt_config, &data_offset));
EXPECT_TRUE(decrypt_config);
EXPECT_EQ(
std::string(kKeyId.data(),
base::span(kKeyId)
.subspan(base::SpanificationSizeofForStdArray(kKeyId))
.data()),
decrypt_config->key_id());
EXPECT_EQ(std::string(
kExpectedIv.data(),
base::span(kExpectedIv)
.subspan(base::SpanificationSizeofForStdArray(kExpectedIv))
.data()),
decrypt_config->iv());
EXPECT_THAT(decrypt_config->subsamples(), ElementsAre(SubsampleEntry(6, 0)));
EXPECT_EQ(10u, data_offset);
}
}