diff --git a/libwvdrmengine/include/WVErrors.h b/libwvdrmengine/include/WVErrors.h index 93193c1a..f45eebc1 100644 --- a/libwvdrmengine/include/WVErrors.h +++ b/libwvdrmengine/include/WVErrors.h @@ -10,12 +10,19 @@ namespace wvdrm { using android::ERROR_DRM_VENDOR_MIN; +using android::ERROR_DRM_VENDOR_MAX; enum { - kErrorNeedProvisioning = ERROR_DRM_VENDOR_MIN, - kErrorDeviceRevoked = ERROR_DRM_VENDOR_MIN + 1, - kErrorIncorrectBufferSize = ERROR_DRM_VENDOR_MIN + 2, - kErrorCDMGeneric = ERROR_DRM_VENDOR_MIN + 3, + kErrorNeedProvisioning = ERROR_DRM_VENDOR_MIN, + kErrorDeviceRevoked = ERROR_DRM_VENDOR_MIN + 1, + kErrorIncorrectBufferSize = ERROR_DRM_VENDOR_MIN + 2, + kErrorCDMGeneric = ERROR_DRM_VENDOR_MIN + 3, + kErrorUnsupportedCrypto = ERROR_DRM_VENDOR_MIN + 4, + kErrorCannotGuaranteeSecurity = ERROR_DRM_VENDOR_MIN + 5, + kErrorExpectedUnencrypted = ERROR_DRM_VENDOR_MIN + 6, + + // Used by crypto test mode + kErrorTestMode = ERROR_DRM_VENDOR_MAX, }; } // namespace wvdrm diff --git a/libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp b/libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp index 30ad844b..a8ae4511 100644 --- a/libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp +++ b/libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp @@ -18,6 +18,7 @@ #include "utils/Errors.h" #include "utils/String8.h" #include "wv_cdm_constants.h" +#include "WVErrors.h" namespace wvdrm { @@ -71,7 +72,8 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE], size_t numSubSamples, void* dstPtr, AString* errorDetailMsg) { if (mode != kMode_Unencrypted && mode != kMode_AES_CTR) { - return ERROR_DRM_CANNOT_HANDLE; + errorDetailMsg->setTo("Encryption mode is not supported by Widevine CDM."); + return kErrorUnsupportedCrypto; } // If the caller requested secure decrypt, verify that we can comply. @@ -82,10 +84,12 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE], if (!isCdmResponseTypeSuccess(res)) { ALOGE("Error querying CDM status: %u", res); - return ERROR_DRM_CANNOT_HANDLE; + errorDetailMsg->setTo("Unable to verify ability to decode securely."); + return kErrorCannotGuaranteeSecurity; } else if (status[QUERY_KEY_SECURITY_LEVEL] != QUERY_VALUE_SECURITY_LEVEL_L1) { - return ERROR_DRM_CANNOT_HANDLE; + errorDetailMsg->setTo("Secure decode is not supported on this device."); + return kErrorCannotGuaranteeSecurity; } } @@ -103,7 +107,9 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE], const SubSample &subSample = subSamples[i]; if (mode == kMode_Unencrypted && subSample.mNumBytesOfEncryptedData != 0) { - return ERROR_DRM_DECRYPT; + errorDetailMsg->setTo("Encrypted subsamples found in allegedly " + "unencrypted data."); + return kErrorExpectedUnencrypted; } // "Decrypt" any unencrypted data. Per the ISO-CENC standard, clear data @@ -117,7 +123,8 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE], if (!isCdmResponseTypeSuccess(res)) { ALOGE("Decrypt error result in session %s during unencrypted block: %d", mSessionId.c_str(), res); - return mapCdmResponseType(res); + errorDetailMsg->setTo("Error decrypting data."); + return kErrorCDMGeneric; } offset += subSample.mNumBytesOfClearData; @@ -134,7 +141,8 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE], if (!isCdmResponseTypeSuccess(res)) { ALOGE("Decrypt error result in session %s during encrypted block: %d", mSessionId.c_str(), res); - return mapCdmResponseType(res); + errorDetailMsg->setTo("Error decrypting data."); + return kErrorCDMGeneric; } offset += subSample.mNumBytesOfEncryptedData; @@ -158,8 +166,8 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE], buf.appendFormat("%02x", digest[i]); } - *errorDetailMsg = AString(buf.string()); - return ERROR_DRM_VENDOR_MIN; + errorDetailMsg->setTo(buf.string()); + return kErrorTestMode; } diff --git a/libwvdrmengine/mediacrypto/test/WVCryptoPlugin_test.cpp b/libwvdrmengine/mediacrypto/test/WVCryptoPlugin_test.cpp index d5cc7db7..936b2414 100644 --- a/libwvdrmengine/mediacrypto/test/WVCryptoPlugin_test.cpp +++ b/libwvdrmengine/mediacrypto/test/WVCryptoPlugin_test.cpp @@ -107,12 +107,17 @@ TEST_F(WVCryptoPluginTest, RejectsSecureDecodeOnL3) { .WillOnce(DoAll(SetArgPointee<0>(l3Map), Return(wvcdm::NO_ERROR))); - ssize_t res = plugin.decrypt(true, keyId, iv, CryptoPlugin::kMode_AES_CTR, - in, subSamples, kSubSampleCount, out, NULL); + AString errorDetailMessage; - EXPECT_LT(res, static_cast(0)) << + ssize_t res = plugin.decrypt(true, keyId, iv, CryptoPlugin::kMode_AES_CTR, + in, subSamples, kSubSampleCount, out, + &errorDetailMessage); + + EXPECT_LT(res, 0) << "WVCryptoPlugin allowed decryption to proceed despite being asked for an " "unsupported security level"; + EXPECT_GT(errorDetailMessage.size(), 0u) << + "WVCryptoPlugin did not report a detailed error message."; } TEST_F(WVCryptoPluginTest, AttemptsToDecrypt) { @@ -144,9 +149,14 @@ TEST_F(WVCryptoPluginTest, AttemptsToDecrypt) { .WillOnce(Return(wvcdm::NO_ERROR)); } + AString errorDetailMessage; + ssize_t res = plugin.decrypt(false, keyId, iv, CryptoPlugin::kMode_AES_CTR, - in, subSamples, kSubSampleCount, out, NULL); + in, subSamples, kSubSampleCount, out, + &errorDetailMessage); EXPECT_EQ(static_cast(kDataSize), res) << "WVCryptoPlugin decrypted the wrong number of bytes"; + EXPECT_EQ(0u, errorDetailMessage.size()) << + "WVCryptoPlugin reported a detailed error message."; } \ No newline at end of file