Merge "Don't add offsets to ion handles" into jb-mr2-dev

This commit is contained in:
Jeff Tinker
2013-04-20 00:16:02 +00:00
committed by Android (Google) Code Review
15 changed files with 63 additions and 41 deletions

View File

@@ -91,6 +91,7 @@ class CdmEngine : public TimerHandler {
const std::vector<uint8_t>& iv, const std::vector<uint8_t>& iv,
size_t block_offset, size_t block_offset,
void* decrypt_buffer, void* decrypt_buffer,
size_t decrypt_buffer_offset,
bool is_video); bool is_video);
// Is the key known to any session? // Is the key known to any session?

View File

@@ -58,6 +58,7 @@ class CdmSession {
const std::vector<uint8_t>& iv, const std::vector<uint8_t>& iv,
size_t block_offset, size_t block_offset,
void* decrypt_buffer, void* decrypt_buffer,
size_t decrypt_buffer_offset,
bool is_video); bool is_video);
// License renewal // License renewal

View File

@@ -71,6 +71,7 @@ class CryptoSession {
const std::vector<uint8_t>& iv, const std::vector<uint8_t>& iv,
size_t block_offset, size_t block_offset,
void* decrypt_buffer, void* decrypt_buffer,
size_t decrypt_buffer_offset,
bool is_video); bool is_video);
private: private:

View File

@@ -676,6 +676,7 @@ CdmResponseType CdmEngine::Decrypt(
const std::vector<uint8_t>& iv, const std::vector<uint8_t>& iv,
size_t block_offset, size_t block_offset,
void* decrypt_buffer, void* decrypt_buffer,
size_t decrypt_buffer_offset,
bool is_video) { bool is_video) {
CdmSessionIter iter = sessions_.find(session_id); CdmSessionIter iter = sessions_.find(session_id);
if (iter == sessions_.end()) { if (iter == sessions_.end()) {
@@ -685,7 +686,8 @@ CdmResponseType CdmEngine::Decrypt(
return iter->second->Decrypt(is_encrypted, key_id, encrypt_buffer, return iter->second->Decrypt(is_encrypted, key_id, encrypt_buffer,
encrypt_length, iv, block_offset, encrypt_length, iv, block_offset,
decrypt_buffer, is_video); decrypt_buffer, decrypt_buffer_offset,
is_video);
} }
bool CdmEngine::IsKeyValid(const KeyId& key_id) { bool CdmEngine::IsKeyValid(const KeyId& key_id) {

View File

@@ -151,6 +151,7 @@ CdmResponseType CdmSession::Decrypt(bool is_encrypted,
const std::vector<uint8_t>& iv, const std::vector<uint8_t>& iv,
size_t block_offset, size_t block_offset,
void* decrypt_buffer, void* decrypt_buffer,
size_t decrypt_buffer_offset,
bool is_video) { bool is_video) {
if (!crypto_session_ || !crypto_session_->IsOpen()) if (!crypto_session_ || !crypto_session_->IsOpen())
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
@@ -168,7 +169,8 @@ CdmResponseType CdmSession::Decrypt(bool is_encrypted,
} }
return crypto_session_->Decrypt(is_encrypted, encrypt_buffer, encrypt_length, return crypto_session_->Decrypt(is_encrypted, encrypt_buffer, encrypt_length,
iv, block_offset, decrypt_buffer, is_video); iv, block_offset, decrypt_buffer,
decrypt_buffer_offset, is_video);
} }
// License renewal // License renewal

View File

@@ -392,6 +392,7 @@ CdmResponseType CryptoSession::Decrypt(bool is_encrypted,
const std::vector<uint8_t>& iv, const std::vector<uint8_t>& iv,
size_t block_offset, size_t block_offset,
void* decrypt_buffer, void* decrypt_buffer,
size_t decrypt_buffer_offset,
bool is_video) { bool is_video) {
if (!is_destination_buffer_type_valid_) { if (!is_destination_buffer_type_valid_) {
if (!SetDestinationBufferType()) if (!SetDestinationBufferType())
@@ -404,11 +405,12 @@ CdmResponseType CryptoSession::Decrypt(bool is_encrypted,
switch (buffer_descriptor.type) { switch (buffer_descriptor.type) {
case OEMCrypto_BufferType_Clear: case OEMCrypto_BufferType_Clear:
buffer_descriptor.buffer.clear.address = buffer_descriptor.buffer.clear.address =
static_cast<uint8_t*>(decrypt_buffer); static_cast<uint8_t*>(decrypt_buffer) + decrypt_buffer_offset;
buffer_descriptor.buffer.clear.max_length = encrypt_length; buffer_descriptor.buffer.clear.max_length = encrypt_length;
break; break;
case OEMCrypto_BufferType_Secure: case OEMCrypto_BufferType_Secure:
buffer_descriptor.buffer.secure.handle = decrypt_buffer; buffer_descriptor.buffer.secure.handle = decrypt_buffer;
buffer_descriptor.buffer.secure.offset = decrypt_buffer_offset;
buffer_descriptor.buffer.secure.max_length = encrypt_length; buffer_descriptor.buffer.secure.max_length = encrypt_length;
break; break;
case OEMCrypto_BufferType_Direct: case OEMCrypto_BufferType_Direct:

View File

@@ -68,7 +68,8 @@ class WvContentDecryptionModule {
size_t encrypt_length, size_t encrypt_length,
const std::vector<uint8_t>& iv, const std::vector<uint8_t>& iv,
size_t block_offset, size_t block_offset,
void* decrypt_buffer); void* decrypt_buffer,
size_t decrypt_buffer_offset);
// Event listener related methods // Event listener related methods
virtual bool AttachEventListener(const CdmSessionId& session_id, virtual bool AttachEventListener(const CdmSessionId& session_id,

View File

@@ -102,10 +102,12 @@ CdmResponseType WvContentDecryptionModule::Decrypt(
size_t encrypt_length, size_t encrypt_length,
const std::vector<uint8_t>& iv, const std::vector<uint8_t>& iv,
size_t block_offset, size_t block_offset,
void* decrypt_buffer) { void* decrypt_buffer,
size_t decrypt_buffer_offset) {
return cdm_engine_->Decrypt(session_id, is_encrypted, key_id, return cdm_engine_->Decrypt(session_id, is_encrypted, key_id,
encrypt_buffer, encrypt_length, iv, encrypt_buffer, encrypt_length, iv,
block_offset, decrypt_buffer, true); block_offset, decrypt_buffer,
decrypt_buffer_offset, true);
} }
bool WvContentDecryptionModule::AttachEventListener( bool WvContentDecryptionModule::AttachEventListener(

View File

@@ -289,7 +289,8 @@ TEST_F(WvCdmRequestLicenseTest, ClearDecryptionTest) {
encrypt_length, encrypt_length,
data.iv, data.iv,
data.block_offset, data.block_offset,
&decrypt_buffer.front())); &decrypt_buffer.front(),
0));
EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(), EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(),
decrypt_buffer.begin())); decrypt_buffer.begin()));
@@ -335,7 +336,8 @@ TEST_F(WvCdmRequestLicenseTest, ClearDecryptionNoKeyTest) {
encrypt_length, encrypt_length,
data.iv, data.iv,
data.block_offset, data.block_offset,
&decrypt_buffer.front())); &decrypt_buffer.front(),
0));
EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(), EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(),
decrypt_buffer.begin())); decrypt_buffer.begin()));
@@ -383,7 +385,8 @@ TEST_F(WvCdmRequestLicenseTest, DecryptionTest) {
encrypt_length, encrypt_length,
data.iv, data.iv,
data.block_offset, data.block_offset,
&decrypt_buffer.front())); &decrypt_buffer.front(),
0));
EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(), EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(),
decrypt_buffer.begin())); decrypt_buffer.begin()));
@@ -458,7 +461,8 @@ TEST_F(WvCdmRequestLicenseTest, SwitchKeyDecryptionTest) {
encrypt_length, encrypt_length,
data[i].iv, data[i].iv,
data[i].block_offset, data[i].block_offset,
&decrypt_buffer.front())); &decrypt_buffer.front(),
0));
EXPECT_TRUE(std::equal(data[i].decrypt_data.begin(), EXPECT_TRUE(std::equal(data[i].decrypt_data.begin(),
data[i].decrypt_data.end(), data[i].decrypt_data.end(),
@@ -500,7 +504,8 @@ TEST_F(WvCdmRequestLicenseTest, PartialBlockDecryptionTest) {
encrypt_length, encrypt_length,
data.iv, data.iv,
data.block_offset, data.block_offset,
&decrypt_buffer.front())); &decrypt_buffer.front(),
0));
EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(), EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(),
decrypt_buffer.begin())); decrypt_buffer.begin()));
@@ -540,7 +545,8 @@ TEST_F(WvCdmRequestLicenseTest, PartialBlockWithOffsetDecryptionTest) {
encrypt_length, encrypt_length,
data.iv, data.iv,
data.block_offset, data.block_offset,
&decrypt_buffer.front())); &decrypt_buffer.front(),
0));
EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(), EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(),
decrypt_buffer.begin())); decrypt_buffer.begin()));

View File

@@ -101,7 +101,7 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE],
CdmResponseType res = mCDM->Decrypt(mSessionId, false, keyId, CdmResponseType res = mCDM->Decrypt(mSessionId, false, keyId,
source + offset, source + offset,
subSample.mNumBytesOfClearData, subSample.mNumBytesOfClearData,
ivVector, 0, dest + offset); ivVector, 0, dest, offset);
if (!isCdmResponseTypeSuccess(res)) { if (!isCdmResponseTypeSuccess(res)) {
ALOGE("Decrypt error result in session %s during unencrypted block: %d", ALOGE("Decrypt error result in session %s during unencrypted block: %d",
@@ -119,7 +119,8 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE],
CdmResponseType res = mCDM->Decrypt(mSessionId, true, keyId, CdmResponseType res = mCDM->Decrypt(mSessionId, true, keyId,
source + offset, source + offset,
subSample.mNumBytesOfEncryptedData, subSample.mNumBytesOfEncryptedData,
ivVector, encrypted_offset % 16, dest + offset); ivVector, encrypted_offset % 16, dest,
offset);
if (!isCdmResponseTypeSuccess(res)) { if (!isCdmResponseTypeSuccess(res)) {
ALOGE("Decrypt error result in session %s during encrypted block: %d", ALOGE("Decrypt error result in session %s during encrypted block: %d",

View File

@@ -23,10 +23,10 @@ using namespace wvdrm;
class MockCDM : public WvContentDecryptionModule { class MockCDM : public WvContentDecryptionModule {
public: public:
MOCK_METHOD8(Decrypt, CdmResponseType(const CdmSessionId&, bool, const KeyId&, MOCK_METHOD9(Decrypt, CdmResponseType(const CdmSessionId&, bool, const KeyId&,
const uint8_t*, size_t, const uint8_t*, size_t,
const std::vector<uint8_t>&, size_t, const std::vector<uint8_t>&, size_t,
void*)); void*, size_t));
MOCK_METHOD1(QueryStatus, CdmResponseType(CdmQueryMap*)); MOCK_METHOD1(QueryStatus, CdmResponseType(CdmQueryMap*));
}; };
@@ -101,22 +101,22 @@ TEST_F(WVCryptoPluginTest, AttemptsToDecrypt) {
EXPECT_CALL(cdm, Decrypt(ElementsAreArray(sessionId, kSessionIdSize), true, EXPECT_CALL(cdm, Decrypt(ElementsAreArray(sessionId, kSessionIdSize), true,
ElementsAreArray(keyId, KEY_ID_SIZE), in, 16, ElementsAreArray(keyId, KEY_ID_SIZE), in, 16,
ElementsAreArray(iv, KEY_IV_SIZE), 0, out)) ElementsAreArray(iv, KEY_IV_SIZE), 0, out, 0))
.WillOnce(Return(wvcdm::NO_ERROR)); .WillOnce(Return(wvcdm::NO_ERROR));
EXPECT_CALL(cdm, Decrypt(ElementsAreArray(sessionId, kSessionIdSize), false, EXPECT_CALL(cdm, Decrypt(ElementsAreArray(sessionId, kSessionIdSize), false,
ElementsAreArray(keyId, KEY_ID_SIZE), in + 16, 16, ElementsAreArray(keyId, KEY_ID_SIZE), in + 16, 16,
ElementsAreArray(iv, KEY_IV_SIZE), 0, out + 16)) ElementsAreArray(iv, KEY_IV_SIZE), 0, out, 16))
.WillOnce(Return(wvcdm::NO_ERROR)); .WillOnce(Return(wvcdm::NO_ERROR));
EXPECT_CALL(cdm, Decrypt(ElementsAreArray(sessionId, kSessionIdSize), true, EXPECT_CALL(cdm, Decrypt(ElementsAreArray(sessionId, kSessionIdSize), true,
ElementsAreArray(keyId, KEY_ID_SIZE), in + 32, 24, ElementsAreArray(keyId, KEY_ID_SIZE), in + 32, 24,
ElementsAreArray(iv, KEY_IV_SIZE), 0, out + 32)) ElementsAreArray(iv, KEY_IV_SIZE), 0, out, 32))
.WillOnce(Return(wvcdm::NO_ERROR)); .WillOnce(Return(wvcdm::NO_ERROR));
EXPECT_CALL(cdm, Decrypt(ElementsAreArray(sessionId, kSessionIdSize), true, EXPECT_CALL(cdm, Decrypt(ElementsAreArray(sessionId, kSessionIdSize), true,
ElementsAreArray(keyId, KEY_ID_SIZE), in + 56, 8, ElementsAreArray(keyId, KEY_ID_SIZE), in + 56, 8,
ElementsAreArray(iv, KEY_IV_SIZE), 8, out + 56)) ElementsAreArray(iv, KEY_IV_SIZE), 8, out, 56))
.WillOnce(Return(wvcdm::NO_ERROR)); .WillOnce(Return(wvcdm::NO_ERROR));
} }
@@ -130,4 +130,4 @@ TEST_F(WVCryptoPluginTest, AttemptsToDecrypt) {
"WVCryptoPlugin decrypted the wrong number of bytes"; "WVCryptoPlugin decrypted the wrong number of bytes";
EXPECT_EQ(0u, errorDetailMessage.size()) << EXPECT_EQ(0u, errorDetailMessage.size()) <<
"WVCryptoPlugin reported a detailed error message."; "WVCryptoPlugin reported a detailed error message.";
} }

View File

@@ -113,6 +113,7 @@ typedef struct {
struct { // type == OEMCrypto_BufferType_Secure struct { // type == OEMCrypto_BufferType_Secure
void* handle; void* handle;
size_t max_length; size_t max_length;
size_t offset;
} secure; } secure;
struct { // type == OEMCrypto_BufferType_Direct struct { // type == OEMCrypto_BufferType_Direct
bool is_video; bool is_video;
@@ -638,11 +639,13 @@ OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session,
* arguments are ignored. * arguments are ignored.
* iv (in) - The initial value block to be used for content decryption. * iv (in) - The initial value block to be used for content decryption.
* This is discussed further below. * This is discussed further below.
* offset (in) - If non-zero, the decryption block boundary is different * block_offset (in) - If non-zero, the decryption block boundary is
* from the start of the data. offset should be subtracted from * different from the start of the data. offset should be subtracted from
* data_addr to compute the starting address of the first decrypted * data_addr to compute the starting address of the first decrypted
* block. The bytes between the decryption block start address and * block. The bytes between the decryption block start address and
* data_addr are discarded after decryption. * data_addr are discarded after decryption. This is only used to adjust
* the start of decryption block. It does not adjust the beginning of the
* source or destination data. 0 <= block_offset < 16.
* out_buffer (in) - A caller-owned descriptor that specifies the * out_buffer (in) - A caller-owned descriptor that specifies the
* handling of the decrypted byte stream. See OEMCrypto_DestbufferDesc * handling of the decrypted byte stream. See OEMCrypto_DestbufferDesc
* for details. * for details.
@@ -690,14 +693,13 @@ OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session,
* Version: * Version:
* This method changed in API version 5. * This method changed in API version 5.
*/ */
OEMCryptoResult OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,
OEMCrypto_DecryptCTR(OEMCrypto_SESSION session, const uint8_t *data_addr,
const uint8_t *data_addr, size_t data_length,
size_t data_length, bool is_encrypted,
bool is_encrypted, const uint8_t *iv,
const uint8_t *iv, size_t block_offset,
size_t offset, const OEMCrypto_DestBufferDesc* out_buffer);
const OEMCrypto_DestBufferDesc* out_buffer);
/* /*
* OEMCrypto_InstallKeybox * OEMCrypto_InstallKeybox

View File

@@ -856,7 +856,7 @@ bool CryptoEngine::DecryptMessage(SessionContext* session,
bool CryptoEngine::DecryptCTR(SessionContext* session, bool CryptoEngine::DecryptCTR(SessionContext* session,
const uint8_t* iv, const uint8_t* iv,
size_t byte_offset, size_t block_offset,
const uint8_t* cipher_data, const uint8_t* cipher_data,
size_t cipher_data_length, size_t cipher_data_length,
bool is_encrypted, bool is_encrypted,
@@ -922,18 +922,18 @@ bool CryptoEngine::DecryptCTR(SessionContext* session,
// Encrypt the IV. // Encrypt the IV.
uint8_t ecount_buf[AES_BLOCK_SIZE]; uint8_t ecount_buf[AES_BLOCK_SIZE];
if (byte_offset != 0) { if (block_offset != 0) {
// The context is needed only when not starting a new block. // The context is needed only when not starting a new block.
AES_encrypt(aes_iv, ecount_buf, &aes_key); AES_encrypt(aes_iv, ecount_buf, &aes_key);
ctr128_inc(aes_iv); ctr128_inc(aes_iv);
} }
// Decryption. // Decryption.
unsigned int byte_offset_cur = byte_offset; unsigned int block_offset_cur = block_offset;
AES_ctr128_encrypt( AES_ctr128_encrypt(
cipher_data, reinterpret_cast<uint8_t*>(clear_data), cipher_data_length, cipher_data, reinterpret_cast<uint8_t*>(clear_data), cipher_data_length,
&aes_key, aes_iv, ecount_buf, &byte_offset_cur); &aes_key, aes_iv, ecount_buf, &block_offset_cur);
if (byte_offset_cur != ((byte_offset + cipher_data_length) % AES_BLOCK_SIZE)) { if (block_offset_cur != ((block_offset + cipher_data_length) % AES_BLOCK_SIZE)) {
LOGE("[DecryptCTR(): FAILURE: byte offset wrong.]"); LOGE("[DecryptCTR(): FAILURE: byte offset wrong.]");
return false; return false;
} }

View File

@@ -234,7 +234,7 @@ class CryptoEngine {
bool DecryptCTR(SessionContext* session, bool DecryptCTR(SessionContext* session,
const uint8_t* iv, const uint8_t* iv,
size_t byte_offset, size_t block_offset,
const uint8_t* cipher_data, const uint8_t* cipher_data,
size_t cipher_data_length, size_t cipher_data_length,
bool is_encrypted, bool is_encrypted,

View File

@@ -501,7 +501,7 @@ OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,
size_t data_length, size_t data_length,
bool is_encrypted, bool is_encrypted,
const uint8_t* iv, const uint8_t* iv,
size_t offset, size_t block_offset,
const OEMCrypto_DestBufferDesc* out_buffer) { const OEMCrypto_DestBufferDesc* out_buffer) {
if (trace_all_calls) { if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,\n"); printf("-- OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,\n");
@@ -517,7 +517,8 @@ OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,
break; break;
case OEMCrypto_BufferType_Secure: case OEMCrypto_BufferType_Secure:
buffer_type = kBufferTypeSecure; buffer_type = kBufferTypeSecure;
destination = out_buffer->buffer.secure.handle; destination = (out_buffer->buffer.secure.handle
+ out_buffer->buffer.secure.offset);
max_length = out_buffer->buffer.secure.max_length; max_length = out_buffer->buffer.secure.max_length;
break; break;
default: default:
@@ -551,7 +552,7 @@ OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,
return OEMCrypto_ERROR_INVALID_CONTEXT; return OEMCrypto_ERROR_INVALID_CONTEXT;
} }
if (!crypto_engine->DecryptCTR(session_ctx, iv, (int)offset, if (!crypto_engine->DecryptCTR(session_ctx, iv, (int)block_offset,
data_addr, data_length, is_encrypted, data_addr, data_length, is_encrypted,
destination, buffer_type)) { destination, buffer_type)) {
LOGE("[OEMCrypto_DecryptCTR(): OEMCrypto_ERROR_DECRYPT_FAILED]"); LOGE("[OEMCrypto_DecryptCTR(): OEMCrypto_ERROR_DECRYPT_FAILED]");