From afae7d93d52372a094a5a49f31819d582cf9bf58 Mon Sep 17 00:00:00 2001 From: "John W. Bruce" Date: Tue, 17 Jan 2017 16:11:46 -0800 Subject: [PATCH] Reduce Duplication in CryptoPlugin (This is a merge of go/wvgerrit/22898) This change moves some code - that was nearly identical between the clear subsample and encrypted subsample paths - into a common helper method. Bug: 31381719 Test: libwvdrmmediacrypto_test Change-Id: I64d3e03b3953cddd1cc0d370ba66fc634dfb1dd8 --- .../mediacrypto/include/WVCryptoPlugin.h | 3 + .../mediacrypto/src/WVCryptoPlugin.cpp | 128 ++++++++---------- 2 files changed, 58 insertions(+), 73 deletions(-) diff --git a/libwvdrmengine/mediacrypto/include/WVCryptoPlugin.h b/libwvdrmengine/mediacrypto/include/WVCryptoPlugin.h index 97c0e3d7..25a1a08b 100644 --- a/libwvdrmengine/mediacrypto/include/WVCryptoPlugin.h +++ b/libwvdrmengine/mediacrypto/include/WVCryptoPlugin.h @@ -45,6 +45,9 @@ class WVCryptoPlugin : public android::CryptoPlugin { wvcdm::CdmSessionId mSessionId; wvcdm::CdmSessionId configureTestMode(const void* data, size_t size); + 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* ivPtr); diff --git a/libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp b/libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp index 2e86543d..506efabe 100644 --- a/libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp +++ b/libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp @@ -189,41 +189,10 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE], params.decrypt_buffer_offset = offset; params.subsample_flags = clearFlags; - CdmResponseType res = mCDM->Decrypt(mSessionId, haveEncryptedSubsamples, - params); - - if (!isCdmResponseTypeSuccess(res)) { - ALOGE("Decrypt error result in session %s during unencrypted block: %d", - mSessionId.c_str(), res); - if (res == wvcdm::INSUFFICIENT_CRYPTO_RESOURCES) { - errorDetailMsg->setTo( - "Error decrypting data: insufficient crypto resources"); - // This error is actionable by the app and should be passed up. - return mapCdmResponseType(res); - } else if (res == wvcdm::NEED_KEY) { - errorDetailMsg->setTo( - "Error decrypting data: requested key has not been loaded"); - // This error is actionable by the app and should be passed up. - return mapCdmResponseType(res); - } else if (res == wvcdm::SESSION_NOT_FOUND_FOR_DECRYPT) { - errorDetailMsg->setTo( - "Error decrypting data: session not found, possibly reclaimed"); - // This error is actionable by the app and should be passed up. - return mapCdmResponseType(res); - } else if (res == wvcdm::DECRYPT_ERROR) { - errorDetailMsg->setTo( - "Error decrypting data: unspecified error"); - // This error is actionable by the app and should be passed up. - return mapCdmResponseType(res); - } else if (res == wvcdm::INSUFFICIENT_OUTPUT_PROTECTION) { - errorDetailMsg->setTo( - "Error decrypting data: insufficient output protection"); - // This error is actionable by the app and should be passed up. - return mapCdmResponseType(res); - } else { - // Swallow the specifics of other errors to obscure decrypt internals. - return kErrorCDMGeneric; - } + status_t res = attemptDecrypt(params, haveEncryptedSubsamples, + errorDetailMsg); + if (res != android::OK) { + return res; } offset += subSample.mNumBytesOfClearData; @@ -239,41 +208,10 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE], params.decrypt_buffer_offset = offset; params.subsample_flags = encryptedFlags; - CdmResponseType res = mCDM->Decrypt(mSessionId, haveEncryptedSubsamples, - params); - - if (!isCdmResponseTypeSuccess(res)) { - ALOGE("Decrypt error result in session %s during encrypted block: %d", - mSessionId.c_str(), res); - if (res == wvcdm::INSUFFICIENT_CRYPTO_RESOURCES) { - errorDetailMsg->setTo( - "Error decrypting data: insufficient crypto resources"); - // This error is actionable by the app and should be passed up. - return mapCdmResponseType(res); - } else if (res == wvcdm::NEED_KEY) { - errorDetailMsg->setTo( - "Error decrypting data: requested key has not been loaded"); - // This error is actionable by the app and should be passed up. - return mapCdmResponseType(res); - } else if (res == wvcdm::SESSION_NOT_FOUND_FOR_DECRYPT) { - errorDetailMsg->setTo( - "Error decrypting data: session not found, possibly reclaimed"); - // This error is actionable by the app and should be passed up. - return mapCdmResponseType(res); - } else if (res == wvcdm::DECRYPT_ERROR) { - errorDetailMsg->setTo( - "Error decrypting data: unspecified error"); - // This error is actionable by the app and should be passed up. - return mapCdmResponseType(res); - } else if (res == wvcdm::INSUFFICIENT_OUTPUT_PROTECTION) { - errorDetailMsg->setTo( - "Error decrypting data: insufficient output protection"); - // This error is actionable by the app and should be passed up. - return mapCdmResponseType(res); - } else { - // Swallow the specifics of other errors to obscure decrypt internals. - return kErrorCDMGeneric; - } + status_t res = attemptDecrypt(params, haveEncryptedSubsamples, + errorDetailMsg); + if (res != android::OK) { + return res; } offset += subSample.mNumBytesOfEncryptedData; @@ -291,9 +229,9 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE], increment = (blockOffset + subSample.mNumBytesOfEncryptedData) / kAESBlockSize; } else { - res = countEncryptedBlocksInPatternedRange( + CdmResponseType countRes = countEncryptedBlocksInPatternedRange( subSample.mNumBytesOfEncryptedData, pattern, &increment); - if (!isCdmResponseTypeSuccess(res)) { + if (!isCdmResponseTypeSuccess(countRes)) { // Swallow the specifics of the error to obscure decrypt internals. return kErrorCDMGeneric; } @@ -342,10 +280,54 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE], return kErrorTestMode; } - return static_cast(offset); } +status_t WVCryptoPlugin::attemptDecrypt(const CdmDecryptionParameters& params, + bool haveEncryptedSubsamples, + AString* errorDetailMsg) { + CdmResponseType res = mCDM->Decrypt(mSessionId, haveEncryptedSubsamples, + params); + + if (isCdmResponseTypeSuccess(res)) { + return android::OK; + } else { + ALOGE("Decrypt error result in session %s during %s block: %d", + mSessionId.c_str(), + params.is_encrypted ? "encrypted" : "unencrypted", + res); + if (res == wvcdm::INSUFFICIENT_CRYPTO_RESOURCES) { + errorDetailMsg->setTo( + "Error decrypting data: insufficient crypto resources"); + // This error is actionable by the app and should be passed up. + return mapCdmResponseType(res); + } else if (res == wvcdm::NEED_KEY) { + errorDetailMsg->setTo( + "Error decrypting data: requested key has not been loaded"); + // This error is actionable by the app and should be passed up. + return mapCdmResponseType(res); + } else if (res == wvcdm::SESSION_NOT_FOUND_FOR_DECRYPT) { + errorDetailMsg->setTo( + "Error decrypting data: session not found, possibly reclaimed"); + // This error is actionable by the app and should be passed up. + return mapCdmResponseType(res); + } else if (res == wvcdm::DECRYPT_ERROR) { + errorDetailMsg->setTo( + "Error decrypting data: unspecified error"); + // This error is actionable by the app and should be passed up. + return mapCdmResponseType(res); + } else if (res == wvcdm::INSUFFICIENT_OUTPUT_PROTECTION) { + errorDetailMsg->setTo( + "Error decrypting data: insufficient output protection"); + // This error is actionable by the app and should be passed up. + return mapCdmResponseType(res); + } else { + // Swallow the specifics of other errors to obscure decrypt internals. + return kErrorCDMGeneric; + } + } +} + CdmResponseType WVCryptoPlugin::countEncryptedBlocksInPatternedRange( size_t range, const Pattern& pattern, uint64_t* result) { if (result == NULL || range % kAESBlockSize != 0) {