Increment IV in WVCryptoPlugin
WVCryptoPlugin was not properly implementing part of its responsibilities to AES-CTR in ISO-CENC. Specifically, it was not incrementing the IV after each block. Also, I have greatly expanded the unit tests for decrypt() to catch more edge cases. This change fixes the two failing test vectors in the Java integration tests. Copied from https://widevine-internal-review.googlesource.com/#/c/5123/2 Bug: 8656421 Change-Id: If935edbf01068f5b0d5254b4e657057ef57d8fcf
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "WVCryptoPlugin.h"
|
||||
|
||||
#include <endian.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -78,13 +79,14 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE],
|
||||
|
||||
// Convert parameters to the form the CDM wishes to consume them in.
|
||||
const KeyId keyId(reinterpret_cast<const char*>(key), KEY_ID_SIZE);
|
||||
const vector<uint8_t> ivVector(iv, iv + KEY_IV_SIZE);
|
||||
vector<uint8_t> ivVector(iv, iv + KEY_IV_SIZE);
|
||||
const uint8_t* const source = static_cast<const uint8_t*>(srcPtr);
|
||||
uint8_t* const dest = static_cast<uint8_t*>(dstPtr);
|
||||
|
||||
// Iterate through subsamples, sending them to the CDM serially.
|
||||
size_t offset = 0;
|
||||
size_t encrypted_offset = 0;
|
||||
static const size_t kAESBlockSize = 16;
|
||||
size_t blockOffset = 0;
|
||||
|
||||
for (size_t i = 0; i < numSubSamples; ++i) {
|
||||
const SubSample &subSample = subSamples[i];
|
||||
@@ -119,8 +121,7 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE],
|
||||
CdmResponseType res = mCDM->Decrypt(mSessionId, true, keyId,
|
||||
source + offset,
|
||||
subSample.mNumBytesOfEncryptedData,
|
||||
ivVector, encrypted_offset % 16, dest,
|
||||
offset);
|
||||
ivVector, blockOffset, dest, offset);
|
||||
|
||||
if (!isCdmResponseTypeSuccess(res)) {
|
||||
ALOGE("Decrypt error result in session %s during encrypted block: %d",
|
||||
@@ -130,7 +131,10 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE],
|
||||
}
|
||||
|
||||
offset += subSample.mNumBytesOfEncryptedData;
|
||||
encrypted_offset += subSample.mNumBytesOfEncryptedData;
|
||||
|
||||
blockOffset += subSample.mNumBytesOfEncryptedData;
|
||||
incrementIV(blockOffset / kAESBlockSize, &ivVector);
|
||||
blockOffset %= kAESBlockSize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,4 +162,10 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE],
|
||||
return static_cast<ssize_t>(offset);
|
||||
}
|
||||
|
||||
void WVCryptoPlugin::incrementIV(uint64_t increaseBy, vector<uint8_t>* ivPtr) {
|
||||
vector<uint8_t>& iv = *ivPtr;
|
||||
uint64_t* counterBuffer = reinterpret_cast<uint64_t*>(&iv[8]);
|
||||
(*counterBuffer) = htonq(ntohq(*counterBuffer) + increaseBy);
|
||||
}
|
||||
|
||||
} // namespace wvdrm
|
||||
|
||||
Reference in New Issue
Block a user