Merge "Fix IV handling for pattern encryption."

This commit is contained in:
John Bruce
2019-01-17 03:07:56 +00:00
committed by Android (Google) Code Review
4 changed files with 20 additions and 58 deletions

View File

@@ -50,8 +50,6 @@ class WVCryptoPlugin : public android::CryptoPlugin {
android::status_t attemptDecrypt(
const wvcdm::CdmDecryptionParameters& params,
bool haveEncryptedSubsamples, android::AString* errorDetailMsg);
static wvcdm::CdmResponseType countEncryptedBlocksInPatternedRange(
size_t range, const Pattern& pattern, uint64_t* result);
static void incrementIV(uint64_t increaseBy, std::vector<uint8_t>* ivPtr);
};

View File

@@ -72,8 +72,6 @@ struct WVCryptoPlugin : public ICryptoPlugin {
Status_V1_2 attemptDecrypt(
const wvcdm::CdmDecryptionParameters& params,
bool haveEncryptedSubsamples, std::string* errorDetailMsg);
static wvcdm::CdmResponseType countEncryptedBlocksInPatternedRange(
size_t range, const Pattern& pattern, uint64_t* result);
static void incrementIV(uint64_t increaseBy, std::vector<uint8_t>* ivPtr);
};

View File

@@ -234,12 +234,16 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE],
increment = (blockOffset + subSample.mNumBytesOfEncryptedData) /
kAESBlockSize;
} else {
CdmResponseType countRes = countEncryptedBlocksInPatternedRange(
subSample.mNumBytesOfEncryptedData, pattern, &increment);
if (!isCdmResponseTypeSuccess(countRes)) {
// Swallow the specifics of the error to obscure decrypt internals.
return kErrorCDMGeneric;
}
const uint64_t numBlocks =
subSample.mNumBytesOfEncryptedData / kAESBlockSize;
const uint64_t patternLengthInBlocks =
pattern.mEncryptBlocks + pattern.mSkipBlocks;
increment =
(numBlocks / patternLengthInBlocks) * pattern.mEncryptBlocks;
// A partial pattern is only encrypted if it is at least
// mEncryptBlocks large.
if (numBlocks % patternLengthInBlocks >= pattern.mEncryptBlocks)
increment += pattern.mEncryptBlocks;
}
incrementIV(increment, &ivVector);
@@ -348,26 +352,6 @@ status_t WVCryptoPlugin::attemptDecrypt(const CdmDecryptionParameters& params,
}
}
CdmResponseType WVCryptoPlugin::countEncryptedBlocksInPatternedRange(
size_t range, const Pattern& pattern, uint64_t* result) {
if (result == NULL || range % kAESBlockSize != 0) {
return wvcdm::UNKNOWN_ERROR;
}
const size_t patternLength = pattern.mEncryptBlocks + pattern.mSkipBlocks;
uint64_t encryptedBlocksPassed = 0;
size_t patternPosition = 0;
for (size_t remaining = range / kAESBlockSize; remaining > 0; --remaining) {
if (patternPosition < pattern.mEncryptBlocks) {
++encryptedBlocksPassed;
}
patternPosition = (patternPosition + 1) % patternLength;
}
*result = encryptedBlocksPassed;
return wvcdm::NO_ERROR;
}
void WVCryptoPlugin::incrementIV(uint64_t increaseBy, vector<uint8_t>* ivPtr) {
vector<uint8_t>& iv = *ivPtr;
uint64_t* counterBuffer = reinterpret_cast<uint64_t*>(&iv[8]);

View File

@@ -338,14 +338,16 @@ Return<void> WVCryptoPlugin::decrypt_1_2(
increment = (blockOffset + subSample.numBytesOfEncryptedData) /
kAESBlockSize;
} else {
CdmResponseType countRes = countEncryptedBlocksInPatternedRange(
subSample.numBytesOfEncryptedData, pattern, &increment);
if (!isCdmResponseTypeSuccess(countRes)) {
// Swallow the specifics of the error to obscure decrypt internals.
_hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"Error decrypting data: unknown error");
return Void();
}
const uint64_t numBlocks =
subSample.numBytesOfEncryptedData / kAESBlockSize;
const uint64_t patternLengthInBlocks =
pattern.encryptBlocks + pattern.skipBlocks;
increment =
(numBlocks / patternLengthInBlocks) * pattern.encryptBlocks;
// A partial pattern is only encrypted if it is at least
// mEncryptBlocks large.
if (numBlocks % patternLengthInBlocks >= pattern.encryptBlocks)
increment += pattern.encryptBlocks;
}
incrementIV(increment, &ivVector);
@@ -429,26 +431,6 @@ Status_V1_2 WVCryptoPlugin::attemptDecrypt(const CdmDecryptionParameters& params
}
}
CdmResponseType WVCryptoPlugin::countEncryptedBlocksInPatternedRange(
size_t range, const Pattern& pattern, uint64_t* result) {
if (result == NULL || range % kAESBlockSize != 0) {
return wvcdm::UNKNOWN_ERROR;
}
const size_t patternLength = pattern.encryptBlocks + pattern.skipBlocks;
uint64_t encryptedBlocksPassed = 0;
size_t patternPosition = 0;
for (size_t remaining = range / kAESBlockSize; remaining > 0; --remaining) {
if (patternPosition < pattern.encryptBlocks) {
++encryptedBlocksPassed;
}
patternPosition = (patternPosition + 1) % patternLength;
}
*result = encryptedBlocksPassed;
return wvcdm::NO_ERROR;
}
void WVCryptoPlugin::incrementIV(uint64_t increaseBy,
std::vector<uint8_t>* ivPtr) {
std::vector<uint8_t>& iv = *ivPtr;