diff --git a/src/browser/wpe/opencdm/open_cdm.cpp b/src/browser/wpe/opencdm/open_cdm.cpp index 5ef511e..fa94e37 100644 --- a/src/browser/wpe/opencdm/open_cdm.cpp +++ b/src/browser/wpe/opencdm/open_cdm.cpp @@ -248,9 +248,12 @@ int OpenCdm::ReleaseMem() { return (false); } -int OpenCdm::Decrypt(unsigned char* encryptedData, uint32_t encryptedDataLength, unsigned char* ivData, uint32_t ivDataLength) { +int OpenCdm::Decrypt(unsigned char* encryptedData, uint32_t encryptedDataLength, unsigned char* ivData, uint32_t ivDataLength, + uint32_t *pdwSubSampleMapping, uint32_t cdwSubSampleMapping, int secureFd, uint32_t secureSize) { int ret = 1; - uint32_t outSize; + uint8_t *out = NULL; + uint32_t out_size = 0; + CDM_DLOG() << "OpenCdm::Decrypt session_id : " << m_session_id.session_id << endl; CDM_DLOG() << "OpenCdm::Decrypt session_id_len : " << m_session_id.session_id_len << endl; CDM_DLOG() << "OpenCdm::Decrypt encryptedDataLength : " << encryptedDataLength << endl; @@ -267,8 +270,18 @@ int OpenCdm::Decrypt(unsigned char* encryptedData, uint32_t encryptedDataLength, } CDM_DLOG() << "Returned back to OpenCdm::Decrypt"; + +#if OCDM_SDP_END2END + out = (uint8_t *)&secureFd; + out_size = secureSize; +#else + out = encryptedData; + out_size = encryptedDataLength; +#endif + DecryptResponse dr = media_engine_->Decrypt((const uint8_t*)ivData, ivDataLength, - (const uint8_t*)encryptedData, encryptedDataLength, (uint8_t*)encryptedData, outSize); + (const uint8_t*)encryptedData, encryptedDataLength, + pdwSubSampleMapping, cdwSubSampleMapping, out, out_size); CDM_DLOG() << "media_engine_->Decrypt done " << dr.platform_response; diff --git a/src/browser/wpe/opencdm/open_cdm.h b/src/browser/wpe/opencdm/open_cdm.h index 6fb0f5a..718c05e 100644 --- a/src/browser/wpe/opencdm/open_cdm.h +++ b/src/browser/wpe/opencdm/open_cdm.h @@ -73,7 +73,7 @@ int Update(uint8_t*, int, std::string&); void SelectKeySystem(const std::string& ); void SelectSession(const std::string& ); bool IsTypeSupported(const std::string& keySystem,const std::string& mimeType); - int Decrypt(unsigned char*, uint32_t, unsigned char*, uint32_t); + int Decrypt(unsigned char*, uint32_t, unsigned char*, uint32_t, uint32_t *, uint32_t, int, uint32_t); int ReleaseMem(); private: diff --git a/src/com/mediaengine/rpc/rpc_cdm_mediaengine_handler.cc b/src/com/mediaengine/rpc/rpc_cdm_mediaengine_handler.cc index 678aea2..e3136aa 100644 --- a/src/com/mediaengine/rpc/rpc_cdm_mediaengine_handler.cc +++ b/src/com/mediaengine/rpc/rpc_cdm_mediaengine_handler.cc @@ -15,19 +15,21 @@ */ #include +#include #include "rpc_cdm_mediaengine_handler.h" #include #include -#ifdef OCDM_SDP_PROTOTYPE +#if OCDM_SDP_ANY #include "socket_client_helper.h" +#if OCDM_SDP_PROTOTYPE #include "ion_allocator_helper.h" - #ifndef ION_SECURE_HEAP_ID_DECODER // VPU secure heap ID is required for SDP prototype #error "ION_SECURE_HEAP_ID_DECODER is not defined" #endif #endif +#endif namespace media { @@ -112,7 +114,7 @@ bool RpcCdmMediaengineHandler::CreateMediaEngineSession(char *session_id_val, << rpc_response->platform_val << ", socket channel ID: " << rpc_response->socket_channel_id; -#ifdef OCDM_SDP_PROTOTYPE +#if OCDM_SDP_ANY /* Connect to the CDMi Service to allow passing the ION file descriptor at every decrypt operation. */ if(this->mSocketClient.Connect(rpc_response->socket_channel_id) < 0) { @@ -145,24 +147,43 @@ int RpcCdmMediaengineHandler::ReleaseMem() { return 1; } DecryptResponse RpcCdmMediaengineHandler::Decrypt(const uint8_t *pbIv, - uint32_t cbIv, - const uint8_t *pbData, - uint32_t cbData, uint8_t *out, - uint32_t &out_size) { + uint32_t cbIv, + const uint8_t *pbData, + uint32_t cbData, + uint32_t *pdwSubSampleMapping, + uint32_t cdwSubSampleMapping, + uint8_t *out, /* For non-SDP and SDP prototype, out is a pointer to a buffer + where to decrypt the data. For SDP, out is a pointer to the + secure ION file descriptor. */ + // TODO: Improve how the file descriptor is provided. + uint32_t &out_size) { + printf("Decrypt-------\n"); CDM_DLOG() << "RpcCdmMediaengineHandler::Decrypt: "; + int err = 0; DecryptResponse response; response.platform_response = PLATFORM_CALL_SUCCESS; response.sys_err = 0; -#ifdef OCDM_SDP_PROTOTYPE + uint8_t *pSubsampleDataShMem = NULL; + +#if OCDM_SDP_ANY int status = 0; + uint32_t secure_size = 0; + int secure_fd = -1; +#if OCDM_SDP_PROTOTYPE IonAllocator ionAlloc; +#endif #endif // TODO(sph): real decryptresponse values need to // be written to sharedmem as well - out_size = 0; + if(out_size < cbData) { + CDM_DLOG() << "Output buffer is too small (cbData: " << cbData << ", out_size: " << out_size << ")."; + response.platform_response = PLATFORM_CALL_FAIL; + out_size = 0; + return response; + } LockSemaphore(idXchngSem, SEM_XCHNG_PUSH); CDM_DLOG() << "LOCKed push lock"; @@ -185,17 +206,35 @@ DecryptResponse RpcCdmMediaengineHandler::Decrypt(const uint8_t *pbIv, // delete[] pbData; CDM_DLOG() << "memcpy pSampleShMem, pbData"; -#ifdef OCDM_SDP_PROTOTYPE + if((pdwSubSampleMapping != NULL) && (cdwSubSampleMapping > 0)) { + shMemInfo->subsampleDataSize = cdwSubSampleMapping * sizeof(uint32_t); + shMemInfo->idSubsampleDataShMem = AllocateSharedMemory(shMemInfo->subsampleDataSize); + pSubsampleDataShMem = reinterpret_cast(MapSharedMemory(shMemInfo->idSubsampleDataShMem)); + memcpy(pSubsampleDataShMem, pdwSubSampleMapping, shMemInfo->subsampleDataSize); + } else { + shMemInfo->subsampleDataSize = 0; + shMemInfo->idSubsampleDataShMem = 0; + } + +#if OCDM_SDP_END2END + secure_size = out_size; + secure_fd = *(int32_t *)out; +#elif OCDM_SDP_PROTOTYPE status = ionAlloc.Allocate(cbData, ION_SECURE_HEAP_ID_DECODER); if(status < 0) { response.platform_response = PLATFORM_CALL_FAIL; goto handle_error; } - CDM_DLOG() << "FD: " << ionAlloc.GetFileDescriptor() << ", size: " << ionAlloc.GetSize() << " bytes"; + secure_fd = ionAlloc.GetFileDescriptor(); + secure_size = ionAlloc.GetSize(); +#endif + +#if OCDM_SDP_ANY + CDM_DLOG() << "Sending secure FD: " << secure_fd << ", size: " << secure_size << " bytes"; // Send file FD - status = this->mSocketClient.SendFileDescriptor(ionAlloc.GetFileDescriptor(), ionAlloc.GetSize()); + status = this->mSocketClient.SendFileDescriptor(secure_fd, secure_size); if(status < 0) { CDM_DLOG() << "Failure to send file descriptor"; response.platform_response = PLATFORM_CALL_FAIL; @@ -203,8 +242,6 @@ DecryptResponse RpcCdmMediaengineHandler::Decrypt(const uint8_t *pbIv, } #endif - shMemInfo->idSubsampleDataShMem = 0; - shMemInfo->subsampleDataSize = 0; CDM_DLOG() << "data ready to decrypt"; UnlockSemaphore(idXchngSem, SEM_XCHNG_DECRYPT); CDM_DLOG() << "WAIT for pull lock"; @@ -212,9 +249,9 @@ DecryptResponse RpcCdmMediaengineHandler::Decrypt(const uint8_t *pbIv, CDM_DLOG() << "LOCKed pull lock"; // process clear data -#ifndef OCDM_SDP_PROTOTYPE +#if OCDM_SDP_DISABLED memcpy(out, pSampleShMem, cbData); -#else +#elif OCDM_SDP_PROTOTYPE CDM_DLOG() << "COPY secure memory to shared memory"; status = ionAlloc.CopyData(out, cbData); if(status < 0) { @@ -223,10 +260,12 @@ DecryptResponse RpcCdmMediaengineHandler::Decrypt(const uint8_t *pbIv, goto handle_error; } #endif - out_size = cbData; -#ifdef OCDM_SDP_PROTOTYPE +#if OCDM_SDP_ANY handle_error: +#endif + +#if OCDM_SDP_PROTOTYPE ionAlloc.Free(); #endif @@ -234,12 +273,26 @@ DecryptResponse RpcCdmMediaengineHandler::Decrypt(const uint8_t *pbIv, UnlockSemaphore(idXchngSem, SEM_XCHNG_PUSH); CDM_DLOG() << "UNLOCKed push lock"; - // clean up current shared mems for sample data - int err = DetachExistingSharedMemory(pIvShMem); - CDM_DLOG() << "detached iv shmem " << shMemInfo->idIvShMem << ": " << err; - err = DetachExistingSharedMemory(pSampleShMem); - CDM_DLOG() << "detached sample shmem " << shMemInfo->idSampleShMem << ": " - << err; + // clean up current shared mems + if(pIvShMem != NULL) { + err = DetachExistingSharedMemory(pIvShMem); + CDM_DLOG() << "detached iv shmem " << shMemInfo->idIvShMem + << ": " << err; + } + + if(pSampleShMem != NULL) { + err = DetachExistingSharedMemory(pSampleShMem); + CDM_DLOG() << "detached sample shmem " << shMemInfo->idSampleShMem + << ": " << err; + } + + if(pSubsampleDataShMem != NULL) { + err = DetachExistingSharedMemory(pSubsampleDataShMem); + CDM_DLOG() << "detached subsample data shmem " << shMemInfo->idSubsampleDataShMem + << ": " << err; + } + + out_size = (response.platform_response == PLATFORM_CALL_SUCCESS) ? cbData : 0; return response; } diff --git a/src/com/mediaengine/rpc/rpc_cdm_mediaengine_handler.h b/src/com/mediaengine/rpc/rpc_cdm_mediaengine_handler.h index ec117bb..ac192f8 100644 --- a/src/com/mediaengine/rpc/rpc_cdm_mediaengine_handler.h +++ b/src/com/mediaengine/rpc/rpc_cdm_mediaengine_handler.h @@ -20,10 +20,11 @@ #include #include +#include #include #include -#ifdef OCDM_SDP_PROTOTYPE +#if OCDM_SDP_ANY #include "socket_client_helper.h" #endif @@ -44,6 +45,7 @@ class RpcCdmMediaengineHandler : public OpenCdmMediaengineCom { DecryptResponse Decrypt(const uint8_t *pbIv, uint32_t cbIv, const uint8_t *pbData, uint32_t cbData, + uint32_t *pdwSubSampleMapping, uint32_t cdwSubSampleMapping, uint8_t *out, uint32_t &out_size) override; int ReleaseMem() override; //TODO (sph): make out const @@ -57,7 +59,7 @@ class RpcCdmMediaengineHandler : public OpenCdmMediaengineCom { CLIENT *rpcClient; -#ifdef OCDM_SDP_PROTOTYPE +#if OCDM_SDP_ANY SocketClient mSocketClient; #endif diff --git a/src/common/open_cdm_common.h b/src/common/open_cdm_common.h index e6a1992..03bb329 100644 --- a/src/common/open_cdm_common.h +++ b/src/common/open_cdm_common.h @@ -30,4 +30,26 @@ namespace media { const char kOpenCdmVersion[] = "1.0.0.0"; } // namespace media + +/* OpenCDM Secure Data Path configuration */ +/* SDP disabled: OpenCDM do not use SDP. When OCDM_SDP is not defined, SDP + is disabled. */ +#define OCDM_SDP_TYPE_DISABLED 0 +/* SDP prototype: OpenCDM allocates a buffer from the ION heap specified by + ION_SECURE_HEAP_ID_DECODER. It decrypts the data into that buffer, maps the + buffer and copies the data into the destination buffer. This assumes that + there is no memory protection on the ION heap. This is used to validate + the ION integration in OpenCDM and DRM layers. */ +#define OCDM_SDP_TYPE_PROTOTYPE 1 +/* End-to-end SDP: OpenCDM gets a file descriptor referencing a secure ION + buffer. It provides the file descriptor to the DRM layer where the data + is decrypted into the secure memory. */ +#define OCDM_SDP_TYPE_END2END 2 + +#define OCDM_SDP_PROTOTYPE (defined(OCDM_SDP) && (OCDM_SDP == OCDM_SDP_TYPE_PROTOTYPE)) +#define OCDM_SDP_END2END (defined(OCDM_SDP) && (OCDM_SDP == OCDM_SDP_TYPE_END2END)) +#define OCDM_SDP_ANY (OCDM_SDP_PROTOTYPE || OCDM_SDP_END2END) +#define OCDM_SDP_DISABLED (!OCDM_SDP_ANY) + + #endif // MEDIA_CDM_PPAPI_EXTERNAL_OPEN_CDM_COMMON_OPEN_CDM_COMMON_H_ diff --git a/src/mediaengine/open_cdm_mediaengine.h b/src/mediaengine/open_cdm_mediaengine.h index 5ee024c..4b6d6bb 100644 --- a/src/mediaengine/open_cdm_mediaengine.h +++ b/src/mediaengine/open_cdm_mediaengine.h @@ -63,6 +63,7 @@ class OpenCdmMediaengine { virtual DecryptResponse Decrypt(const uint8_t *pbIv, uint32_t cbIv, const uint8_t *pbData, uint32_t cbData, + uint32_t *pdwSubSampleMapping, uint32_t cdwSubSampleMapping, uint8_t *out, uint32_t &out_size) = 0; virtual int ReleaseMem() = 0; diff --git a/src/mediaengine/open_cdm_mediaengine_impl.cc b/src/mediaengine/open_cdm_mediaengine_impl.cc index d007579..6240d02 100644 --- a/src/mediaengine/open_cdm_mediaengine_impl.cc +++ b/src/mediaengine/open_cdm_mediaengine_impl.cc @@ -52,14 +52,18 @@ OpenCdmMediaengineImpl::~OpenCdmMediaengineImpl() { DecryptResponse OpenCdmMediaengineImpl::Decrypt(const uint8_t *pbIv, uint32_t cbIv, const uint8_t *pbData, - uint32_t cbData, uint8_t *out, + uint32_t cbData, + uint32_t *pdwSubSampleMapping, + uint32_t cdwSubSampleMapping, + uint8_t *out, uint32_t &out_size) { printf("_------ Decrypt \n"); CDM_DLOG() << "OpenCdmMediaengineImpl::Decrypt: "; DecryptResponse response; - response = media_engine_com_->Decrypt(pbIv, cbIv, pbData, cbData, out, - out_size); + response = media_engine_com_->Decrypt(pbIv, cbIv, pbData, cbData, + pdwSubSampleMapping, cdwSubSampleMapping, + out, out_size); return response; } diff --git a/src/mediaengine/open_cdm_mediaengine_impl.h b/src/mediaengine/open_cdm_mediaengine_impl.h index 0b5086c..1dd0b21 100644 --- a/src/mediaengine/open_cdm_mediaengine_impl.h +++ b/src/mediaengine/open_cdm_mediaengine_impl.h @@ -41,6 +41,7 @@ class OpenCdmMediaengineImpl : public OpenCdmMediaengine { // synchronous decryption DecryptResponse Decrypt(const uint8_t *pbIv, uint32_t cbIv, const uint8_t *pbData, uint32_t cbData, + uint32_t *pdwSubSampleMapping, uint32_t cdwSubSampleMapping, uint8_t *out, uint32_t &out_size) override; int ReleaseMem() override;