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:
John "Juce" Bruce
2013-04-22 14:00:46 -07:00
parent bb0c62768a
commit 088288cb76
3 changed files with 91 additions and 39 deletions

View File

@@ -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