Add tests to validate key length for clearkey plugin.
am: cc77a50e96
Change-Id: Id61b8d76ef30a6c66edd10cd48b4ecdad795165d
This commit is contained in:
commit
01802815eb
1 changed files with 105 additions and 12 deletions
|
@ -84,6 +84,10 @@ static const uint8_t kInvalidUUID[16] = {
|
|||
0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
|
||||
0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80};
|
||||
|
||||
static const uint32_t k256SubSampleByteCount = 256;
|
||||
static const uint32_t k512SubSampleClearBytes = 512;
|
||||
static const uint32_t k512SubSampleEncryptedBytes = 512;
|
||||
|
||||
class DrmHalClearkeyFactoryTest : public ::testing::VtsHalHidlTargetTestBase {
|
||||
public:
|
||||
virtual void SetUp() override {
|
||||
|
@ -931,6 +935,8 @@ class DrmHalClearkeyDecryptTest : public DrmHalClearkeyPluginTest {
|
|||
const hidl_vec<SubSample>& subSamples, const vector<uint8_t>& key);
|
||||
void aes_cbc_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv,
|
||||
const hidl_vec<SubSample>& subSamples, const vector<uint8_t>& key);
|
||||
void decryptWithInvalidKeys(hidl_vec<uint8_t>& invalidResponse,
|
||||
vector<uint8_t>& iv, const Pattern& noPattern, const vector<SubSample>& subSamples);
|
||||
};
|
||||
|
||||
void DrmHalClearkeyDecryptTest::fillRandom(const sp<IMemory>& memory) {
|
||||
|
@ -1088,16 +1094,14 @@ TEST_F(DrmHalClearkeyDecryptTest, TestQueryKeyStatus) {
|
|||
EXPECT_OK(res);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Positive decrypt test. "Decrypt" a single clear segment
|
||||
*/
|
||||
TEST_F(DrmHalClearkeyDecryptTest, ClearSegmentTest) {
|
||||
vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
|
||||
const Pattern noPattern = {0, 0};
|
||||
const uint32_t kByteCount = 256;
|
||||
const vector<SubSample> subSamples = {
|
||||
{.numBytesOfClearData = kByteCount,
|
||||
{.numBytesOfClearData = k256SubSampleByteCount,
|
||||
.numBytesOfEncryptedData = 0}};
|
||||
auto sessionId = openSession();
|
||||
loadKeys(sessionId);
|
||||
|
@ -1108,7 +1112,7 @@ TEST_F(DrmHalClearkeyDecryptTest, ClearSegmentTest) {
|
|||
const bool kNotSecure = false;
|
||||
uint32_t byteCount = decrypt(Mode::UNENCRYPTED, &iv[0], subSamples,
|
||||
noPattern, Status::OK);
|
||||
EXPECT_EQ(kByteCount, byteCount);
|
||||
EXPECT_EQ(k256SubSampleByteCount, byteCount);
|
||||
|
||||
closeSession(sessionId);
|
||||
}
|
||||
|
@ -1120,12 +1124,9 @@ TEST_F(DrmHalClearkeyDecryptTest, ClearSegmentTest) {
|
|||
TEST_F(DrmHalClearkeyDecryptTest, EncryptedAesCtrSegmentTest) {
|
||||
vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
|
||||
const Pattern noPattern = {0, 0};
|
||||
const uint32_t kClearBytes = 512;
|
||||
const uint32_t kEncryptedBytes = 512;
|
||||
const vector<SubSample> subSamples = {
|
||||
{.numBytesOfClearData = kClearBytes,
|
||||
.numBytesOfEncryptedData = kEncryptedBytes
|
||||
}};
|
||||
{.numBytesOfClearData = k512SubSampleClearBytes,
|
||||
.numBytesOfEncryptedData = k512SubSampleEncryptedBytes}};
|
||||
auto sessionId = openSession();
|
||||
loadKeys(sessionId);
|
||||
|
||||
|
@ -1135,10 +1136,11 @@ TEST_F(DrmHalClearkeyDecryptTest, EncryptedAesCtrSegmentTest) {
|
|||
const bool kNotSecure = false;
|
||||
uint32_t byteCount = decrypt(Mode::AES_CTR, &iv[0], subSamples,
|
||||
noPattern, Status::OK);
|
||||
EXPECT_EQ(kClearBytes + kEncryptedBytes, byteCount);
|
||||
EXPECT_EQ(k512SubSampleClearBytes + k512SubSampleEncryptedBytes, byteCount);
|
||||
|
||||
closeSession(sessionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Negative decrypt test. Decrypt without loading keys.
|
||||
*/
|
||||
|
@ -1146,8 +1148,8 @@ TEST_F(DrmHalClearkeyDecryptTest, EncryptedAesCtrSegmentTestNoKeys) {
|
|||
vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
|
||||
const Pattern noPattern = {0, 0};
|
||||
const vector<SubSample> subSamples = {
|
||||
{.numBytesOfClearData = 256,
|
||||
.numBytesOfEncryptedData = 256}};
|
||||
{.numBytesOfClearData = k256SubSampleByteCount,
|
||||
.numBytesOfEncryptedData = k256SubSampleByteCount}};
|
||||
auto sessionId = openSession();
|
||||
|
||||
Status status = cryptoPlugin->setMediaDrmSession(sessionId);
|
||||
|
@ -1160,3 +1162,94 @@ TEST_F(DrmHalClearkeyDecryptTest, EncryptedAesCtrSegmentTestNoKeys) {
|
|||
|
||||
closeSession(sessionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to test decryption with invalid keys is returned
|
||||
*/
|
||||
void DrmHalClearkeyDecryptTest::decryptWithInvalidKeys(
|
||||
hidl_vec<uint8_t>& invalidResponse,
|
||||
vector<uint8_t>& iv,
|
||||
const Pattern& noPattern,
|
||||
const vector<SubSample>& subSamples) {
|
||||
auto sessionId = openSession();
|
||||
|
||||
auto res = drmPlugin->provideKeyResponse(
|
||||
sessionId, invalidResponse,
|
||||
[&](Status status, const hidl_vec<uint8_t>& myKeySetId) {
|
||||
EXPECT_EQ(Status::OK, status);
|
||||
EXPECT_EQ(0u, myKeySetId.size());
|
||||
});
|
||||
ASSERT_OK(res);
|
||||
|
||||
ASSERT_TRUE(cryptoPlugin->setMediaDrmSession(sessionId).isOk());
|
||||
|
||||
uint32_t byteCount = decrypt(Mode::AES_CTR, &iv[0], subSamples,
|
||||
noPattern, Status::ERROR_DRM_NO_LICENSE);
|
||||
EXPECT_EQ(0u, byteCount);
|
||||
|
||||
closeSession(sessionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Negative decrypt test. Decrypt with invalid key.
|
||||
*/
|
||||
TEST_F(DrmHalClearkeyDecryptTest, DecryptWithEmptyKey) {
|
||||
vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
|
||||
const Pattern noPattern = {0, 0};
|
||||
const vector<SubSample> subSamples = {
|
||||
{.numBytesOfClearData = k512SubSampleClearBytes,
|
||||
.numBytesOfEncryptedData = k512SubSampleEncryptedBytes}};
|
||||
|
||||
// base 64 encoded JSON response string, must not contain padding character '='
|
||||
const hidl_string emptyKeyResponse =
|
||||
"{\"keys\":[" \
|
||||
"{" \
|
||||
"\"kty\":\"oct\"" \
|
||||
"\"alg\":\"A128KW2\"" \
|
||||
"\"k\":\"SGVsbG8gRnJpZW5kIQ\"" \
|
||||
"\"kid\":\"Y2xlYXJrZXlrZXlpZDAyAy\"" \
|
||||
"}" \
|
||||
"{" \
|
||||
"\"kty\":\"oct\"," \
|
||||
"\"alg\":\"A128KW2\"" \
|
||||
"\"kid\":\"Y2xlYXJrZXlrZXlpZDAzAy\"," \
|
||||
// empty key follows
|
||||
"\"k\":\"R\"" \
|
||||
"}]" \
|
||||
"}";
|
||||
const size_t kEmptyKeyResponseSize = emptyKeyResponse.size();
|
||||
|
||||
hidl_vec<uint8_t> invalidResponse;
|
||||
invalidResponse.resize(kEmptyKeyResponseSize);
|
||||
memcpy(invalidResponse.data(), emptyKeyResponse.c_str(), kEmptyKeyResponseSize);
|
||||
decryptWithInvalidKeys(invalidResponse, iv, noPattern, subSamples);
|
||||
}
|
||||
|
||||
/**
|
||||
* Negative decrypt test. Decrypt with a key exceeds AES_BLOCK_SIZE.
|
||||
*/
|
||||
TEST_F(DrmHalClearkeyDecryptTest, DecryptWithKeyTooLong) {
|
||||
vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
|
||||
const Pattern noPattern = {0, 0};
|
||||
const vector<SubSample> subSamples = {
|
||||
{.numBytesOfClearData = k512SubSampleClearBytes,
|
||||
.numBytesOfEncryptedData = k512SubSampleEncryptedBytes}};
|
||||
|
||||
// base 64 encoded JSON response string, must not contain padding character '='
|
||||
const hidl_string keyTooLongResponse =
|
||||
"{\"keys\":[" \
|
||||
"{" \
|
||||
"\"kty\":\"oct\"," \
|
||||
"\"alg\":\"A128KW2\"" \
|
||||
"\"kid\":\"Y2xlYXJrZXlrZXlpZDAzAy\"," \
|
||||
// key too long
|
||||
"\"k\":\"V2lubmllIHRoZSBwb29oIVdpbm5pZSB0aGUgcG9vaCE=\"" \
|
||||
"}]" \
|
||||
"}";
|
||||
const size_t kKeyTooLongResponseSize = keyTooLongResponse.size();
|
||||
|
||||
hidl_vec<uint8_t> invalidResponse;
|
||||
invalidResponse.resize(kKeyTooLongResponseSize);
|
||||
memcpy(invalidResponse.data(), keyTooLongResponse.c_str(), kKeyTooLongResponseSize);
|
||||
decryptWithInvalidKeys(invalidResponse, iv, noPattern, subSamples);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue