Merge "Fix IV handling for pattern encryption."
This commit is contained in:
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user