From ae99bb6d11cdff22fbbc2f02371108aa20ce1400 Mon Sep 17 00:00:00 2001 From: Rahul Frias Date: Tue, 19 Jan 2016 16:23:40 -0800 Subject: [PATCH] Verify cipher block mode during decryption [ Merge from http://go/wvgerrit/16498 ] The CDM now supports AES CTR and CBC block cipher modes. The license specifies the mode to be used in the key container. The mode is also specified in mediaCrypto when calling decrypt. This adds verification for the cipher block mode. Change-Id: I2587fc1e4b6d77161f2f8653f8516024c73dd8ac --- libwvdrmengine/cdm/core/include/crypto_session.h | 2 ++ libwvdrmengine/cdm/core/include/wv_cdm_types.h | 4 ++++ libwvdrmengine/cdm/core/src/crypto_session.cpp | 7 ++++++- libwvdrmengine/include/WVErrors.h | 3 ++- libwvdrmengine/include/mapErrors-inl.h | 2 ++ 5 files changed, 16 insertions(+), 2 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/crypto_session.h b/libwvdrmengine/cdm/core/include/crypto_session.h index 1e8d52c2..0b9d0527 100644 --- a/libwvdrmengine/cdm/core/include/crypto_session.h +++ b/libwvdrmengine/cdm/core/include/crypto_session.h @@ -134,6 +134,8 @@ class CryptoSession { uint64_t request_id_base_; static uint64_t request_id_index_; + CdmCipherMode cipher_mode_; + CORE_DISALLOW_COPY_AND_ASSIGN(CryptoSession); }; diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_types.h b/libwvdrmengine/cdm/core/include/wv_cdm_types.h index 456597f4..b638f577 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_types.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_types.h @@ -214,6 +214,7 @@ enum CdmResponseType { LOAD_USAGE_INFO_FILE_ERROR, LOAD_USAGE_INFO_MISSING, SESSION_FILE_HANDLE_INIT_ERROR, + INCORRECT_CRYPTO_MODE, }; enum CdmKeyStatus { @@ -295,6 +296,7 @@ struct CdmCencPatternEncryptionDescriptor { struct CdmDecryptionParameters { bool is_encrypted; bool is_secure; + CdmCipherMode cipher_mode; const KeyId* key_id; const uint8_t* encrypt_buffer; size_t encrypt_length; @@ -309,6 +311,7 @@ struct CdmDecryptionParameters { CdmDecryptionParameters() : is_encrypted(true), is_secure(true), + cipher_mode(kCipherModeCtr), key_id(NULL), encrypt_buffer(NULL), encrypt_length(0), @@ -325,6 +328,7 @@ struct CdmDecryptionParameters { size_t offset, void* decrypted_buffer) : is_encrypted(true), is_secure(true), + cipher_mode(kCipherModeCtr), key_id(key), encrypt_buffer(encrypted_buffer), encrypt_length(encrypted_length), diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index e721dcf3..2a81ebf8 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -40,7 +40,8 @@ CryptoSession::CryptoSession() update_usage_table_after_close_session_(false), is_destination_buffer_type_valid_(false), requested_security_level_(kLevelDefault), - request_id_base_(0) { + request_id_base_(0), + cipher_mode_(kCipherModeCtr) { Init(); } @@ -415,6 +416,7 @@ CdmResponseType CryptoSession::LoadKeys( ko->cipher_mode = ki->cipher_mode() == kCipherModeCbc ? OEMCrypto_CipherMode_CBC : OEMCrypto_CipherMode_CTR; + cipher_mode_ = ki->cipher_mode(); } uint8_t* pst = NULL; if (!provider_session_token.empty()) { @@ -674,6 +676,9 @@ CdmResponseType CryptoSession::Decrypt(const CdmDecryptionParameters& params) { params.encrypt_buffer, params.encrypt_length, &buffer_descriptor, params.subsample_flags); } + if (params.cipher_mode != cipher_mode_) { + return INCORRECT_CRYPTO_MODE; + } if (params.is_encrypted || sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) { OEMCrypto_CENCEncryptPatternDesc pattern_descriptor; pattern_descriptor.encrypt = params.pattern_descriptor.encrypt_blocks; diff --git a/libwvdrmengine/include/WVErrors.h b/libwvdrmengine/include/WVErrors.h index a05f25de..ee5e18b4 100644 --- a/libwvdrmengine/include/WVErrors.h +++ b/libwvdrmengine/include/WVErrors.h @@ -184,7 +184,8 @@ enum { kLoadUsageInfoFileError = ERROR_DRM_VENDOR_MIN + 170, kLoadUsageInfoMissing = ERROR_DRM_VENDOR_MIN + 171, kSessionFileHandleInitError = ERROR_DRM_VENDOR_MIN + 172, - kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 172, + kIncorrectCryptoMode = ERROR_DRM_VENDOR_MIN + 173, + kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 173, // Used by crypto test mode kErrorTestMode = ERROR_DRM_VENDOR_MAX, diff --git a/libwvdrmengine/include/mapErrors-inl.h b/libwvdrmengine/include/mapErrors-inl.h index fcd8868f..eef2a875 100644 --- a/libwvdrmengine/include/mapErrors-inl.h +++ b/libwvdrmengine/include/mapErrors-inl.h @@ -351,6 +351,8 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kLoadUsageInfoMissing; case wvcdm::SESSION_FILE_HANDLE_INIT_ERROR: return kSessionFileHandleInitError; + case wvcdm::INCORRECT_CRYPTO_MODE: + return kIncorrectCryptoMode; case wvcdm::UNKNOWN_ERROR: return android::ERROR_DRM_UNKNOWN; case wvcdm::SECURE_BUFFER_REQUIRED: