From 05e767638571bc50d7a26471fbe07005f3c875fa Mon Sep 17 00:00:00 2001 From: Jungtae Kim Date: Tue, 2 Oct 2012 16:08:56 -0700 Subject: [PATCH] hardware: samsung_slsi: exynos5: add secure path configure API The library includes two interfaces: - CP_Enable_Path_Protection() - CP_Disable_Path_Protection() The first one is should be called before start of DRM playback. The second one is should be called after end of DRM playback Bug: 7287429 Change-Id: I44aab1cca7638fb8eac3d3fc90154c5382d8c71a Signed-off-by: Jungtae Kim [ dima: fixed extern to C and make files ] Signed-off-by: Dima Zavin --- Android.mk | 3 +- include/content_protect.h | 44 +++++++ libsecurepath/Android.mk | 37 ++++++ libsecurepath/content_protect.cpp | 192 ++++++++++++++++++++++++++++ libsecurepath/tci.h | 55 ++++++++ libsecurepath/tlc_communication.cpp | 131 +++++++++++++++++++ libsecurepath/tlc_communication.h | 39 ++++++ libsecurepath/tlwvdrm_api.h | 77 +++++++++++ 8 files changed, 577 insertions(+), 1 deletion(-) create mode 100755 include/content_protect.h create mode 100644 libsecurepath/Android.mk create mode 100644 libsecurepath/content_protect.cpp create mode 100644 libsecurepath/tci.h create mode 100644 libsecurepath/tlc_communication.cpp create mode 100644 libsecurepath/tlc_communication.h create mode 100644 libsecurepath/tlwvdrm_api.h diff --git a/Android.mk b/Android.mk index 6011710..f279e33 100644 --- a/Android.mk +++ b/Android.mk @@ -32,7 +32,8 @@ exynos5_dirs := \ libcamera2 \ mobicore \ libkeymaster \ - gralloc + gralloc \ + libsecurepath BOARD_USE_V4L2 := true BOARD_USE_V4L2_ION := true diff --git a/include/content_protect.h b/include/content_protect.h new file mode 100755 index 0000000..4d06e0a --- /dev/null +++ b/include/content_protect.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2012 Samsung Electronics Co., LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTENT_PROTECT_H__ +#define __CONTENT_PROTECT_H__ + +__BEGIN_DECLS + +typedef enum { + CP_SUCCESS = 0, + CP_ERROR_ENABLE_PATH_PROTECTION_FAILED, + CP_ERROR_DISABLE_PATH_PROTECTION_FAILED, +} cpResult_t; + + +/** + * protection IP + */ +#define CP_PROTECT_MFC 0x00000001 +#define CP_PROTECT_GSC0 0x00000002 +#define CP_PROTECT_GSC3 0x00000004 +#define CP_PROTECT_FIMD 0x00000008 +#define CP_PROTECT_MIXER 0x00000010 + + +cpResult_t CP_Enable_Path_Protection(uint32_t); +cpResult_t CP_Disable_Path_Protection(uint32_t); + +__END_DECLS + +#endif diff --git a/libsecurepath/Android.mk b/libsecurepath/Android.mk new file mode 100644 index 0000000..de8f4e6 --- /dev/null +++ b/libsecurepath/Android.mk @@ -0,0 +1,37 @@ +# +# +# Copyright (C) 2009 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +LOCAL_PATH := $(call my-dir) + + +############################################################################### +# libcsecurepath.a +include $(CLEAR_VARS) +LOCAL_MODULE := libsecurepath +BUILD_DATE := \"`date '+%Y.%m.%d'`\" +LOCAL_CPPFLAGS := -Wall -D_BUILD_DATE=$(BUILD_DATE) +LOCAL_SRC_FILES += \ + tlc_communication.cpp \ + content_protect.cpp \ + +LOCAL_C_INCLUDES := hardware/samsung_slsi/exynos5/include + +LOCAL_SHARED_LIBRARIES += libMcClient + +include hardware/samsung_slsi/exynos5/mobicore/common/LogWrapper/Android.mk + +include $(BUILD_STATIC_LIBRARY) diff --git a/libsecurepath/content_protect.cpp b/libsecurepath/content_protect.cpp new file mode 100644 index 0000000..a1a1d5e --- /dev/null +++ b/libsecurepath/content_protect.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2012 Samsung Electronics Co., LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "tlwvdrm_api.h" +#define LOG_TAG "drm_content_protect" +#include "log.h" +#include "tlc_communication.h" +#include "content_protect.h" + +mc_comm_ctx cp_ctx; + +// ------------------------------------------------------------- +static mcResult_t tlc_initialize(void) { + mcResult_t mcRet; + + memset(&cp_ctx, 0x00, sizeof(cp_ctx)); + cp_ctx.device_id = MC_DEVICE_ID_DEFAULT; + cp_ctx.uuid = (mcUuid_t)TL_WV_DRM_UUID; + cp_ctx.initialized = false; + + mcRet = tlc_open(&cp_ctx); + if (MC_DRV_OK != mcRet) { + LOG_E("open TL session failed!"); + return mcRet; + } + + cp_ctx.initialized = true; + + return MC_DRV_OK; +} + +// ------------------------------------------------------------- +static mcResult_t tlc_terminate(void) { + mcResult_t mcRet; + + if (cp_ctx.initialized == true) { + mcRet = tlc_close(&cp_ctx); + if (MC_DRV_OK != mcRet) { + LOG_E("close TL session failed!"); + return mcRet; + } + + memset(&cp_ctx, 0x00, sizeof(cp_ctx)); + cp_ctx.initialized = false; + } + + return MC_DRV_OK; +} + +extern "C" cpResult_t CP_Enable_Path_Protection(uint32_t protect_ip) +{ + cpResult_t cp_result = CP_SUCCESS; + mcResult_t mcRet; + tciMessage_t *tci = NULL; + + LOG_I("[CONTENT_PROTECT] : CP_Enable_Path_Protection"); + do { + // ------------------------------------------------------------- + // Step 1: Call the Trustlet Open function. + mcRet = tlc_initialize(); + if (MC_DRV_OK != mcRet) { + LOG_E("Tlc Open Error"); + cp_result = CP_ERROR_ENABLE_PATH_PROTECTION_FAILED; + break; + } + + // ------------------------------------------------------------- + // Step 2: Check TCI buffer. + tci = cp_ctx.tci_msg; + if (NULL == tci) { + LOG_E("TCI has not been set up properly - exiting"); + cp_result = CP_ERROR_ENABLE_PATH_PROTECTION_FAILED; + break; + } + + // ------------------------------------------------------------- + // Step 3: Call the Trustlet functions + // Step 3.1: Prepare command message in TCI + tci->cmd.id = CMD_WV_DRM_ENABLE_PATH_PROTECTION; + memcpy(tci->cmd.data, &protect_ip, sizeof(protect_ip)); + tci->cmd.data_len = sizeof(protect_ip); + + // ------------------------------------------------------------- + // Step 3.2: Send Trustlet TCI Message + mcRet = tlc_communicate(&cp_ctx); + if (MC_DRV_OK != mcRet) { + LOG_E("Tlc Communicate Error"); + cp_result = CP_ERROR_ENABLE_PATH_PROTECTION_FAILED; + break; + } + + // ------------------------------------------------------------- + // Step 3.3: Verify that the Trustlet sent a response + if ((RSP_ID(CMD_WV_DRM_ENABLE_PATH_PROTECTION) != tci->resp.id)) { + LOG_E("Trustlet did not send a response: %d", tci->resp.id); + cp_result = CP_ERROR_ENABLE_PATH_PROTECTION_FAILED; + break; + } + + // ------------------------------------------------------------- + // Step 3.4: Check the Trustlet return code + if (tci->resp.return_code != RET_TL_WV_DRM_OK) { + LOG_E("Trustlet did not send a valid return code: %d", tci->resp.return_code); + cp_result = CP_ERROR_ENABLE_PATH_PROTECTION_FAILED; + break; + } + } while(0); + + tlc_terminate(); + LOG_I("[CONTENT_PROTECT] : CP_Enable_Path_Protection. return value(%d)", cp_result); + return cp_result; +} + +extern "C" cpResult_t CP_Disable_Path_Protection(uint32_t protect_ip) +{ + cpResult_t cp_result = CP_SUCCESS; + mcResult_t mcRet; + tciMessage_t *tci = NULL; + + LOG_I("[CONTENT_PROTECT] : CP_Disable_Path_Protection"); + do { + // ------------------------------------------------------------- + // Step 1: Call the Trustlet Open function. + mcRet = tlc_initialize(); + if (MC_DRV_OK != mcRet) { + LOG_E("Tlc Open Error"); + cp_result = CP_ERROR_DISABLE_PATH_PROTECTION_FAILED; + break; + } + + // ------------------------------------------------------------- + // Step 2: Check TCI buffer. + tci = cp_ctx.tci_msg; + if (NULL == tci) { + LOG_E("TCI has not been set up properly - exiting"); + cp_result = CP_ERROR_DISABLE_PATH_PROTECTION_FAILED; + break; + } + + // ------------------------------------------------------------- + // Step 3: Call the Trustlet functions + // Step 3.1: Prepare command message in TCI + tci->cmd.id = CMD_WV_DRM_DISABLE_PATH_PROTECTION; + memcpy(tci->cmd.data, &protect_ip, sizeof(protect_ip)); + tci->cmd.data_len = sizeof(protect_ip); + + // ------------------------------------------------------------- + // Step 3.2: Send Trustlet TCI Message + mcRet = tlc_communicate(&cp_ctx); + if (MC_DRV_OK != mcRet) { + LOG_E("Tlc Communicate Error"); + cp_result = CP_ERROR_DISABLE_PATH_PROTECTION_FAILED; + break; + } + + // ------------------------------------------------------------- + // Step 3.3: Verify that the Trustlet sent a response + if ((RSP_ID(CMD_WV_DRM_DISABLE_PATH_PROTECTION) != tci->resp.id)) { + LOG_E("Trustlet did not send a response: %d", tci->resp.id); + cp_result = CP_ERROR_DISABLE_PATH_PROTECTION_FAILED; + break; + } + + // ------------------------------------------------------------- + // Step 3.4: Check the Trustlet return code + if (tci->resp.return_code != RET_TL_WV_DRM_OK) { + LOG_E("Trustlet did not send a valid return code: %d", tci->resp.return_code); + cp_result = CP_ERROR_DISABLE_PATH_PROTECTION_FAILED; + break; + } + } while(0); + + tlc_terminate(); + LOG_I("[CONTENT_PROTECT] : CP_Disable_Path_Protection. return value(%d)", cp_result); + return cp_result; +} + diff --git a/libsecurepath/tci.h b/libsecurepath/tci.h new file mode 100644 index 0000000..0365eb3 --- /dev/null +++ b/libsecurepath/tci.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2012 Samsung Electronics Co., LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef TCI_H_ +#define TCI_H_ + +typedef uint32_t tciCommandId_t; +typedef uint32_t tciResponseId_t; +typedef uint32_t tciReturnCode_t; + +/**< Responses have bit 31 set */ +#define RSP_ID_MASK (1U << 31) +#define RSP_ID(cmdId) (((uint32_t)(cmdId)) | RSP_ID_MASK) +#define IS_CMD(cmdId) ((((uint32_t)(cmdId)) & RSP_ID_MASK) == 0) +#define IS_RSP(cmdId) ((((uint32_t)(cmdId)) & RSP_ID_MASK) == RSP_ID_MASK) + +/** + * Return codes of Trustlet commands. + */ +#define RET_OK 0 /**< Set, if processing is error free */ +#define RET_ERR_UNKNOWN_CMD 1 /**< Unknown command */ +#define RET_CUSTOM_START 2 +#define RET_ERR_MAP 3 +#define RET_ERR_UNMAP 4 + +/** + * TCI command header. + */ +typedef struct { + tciCommandId_t commandId; /**< Command ID */ +} tciCommandHeader_t; + +/** + * TCI response header. + */ +typedef struct { + tciResponseId_t responseId; /**< Response ID (must be command ID | RSP_ID_MASK )*/ + tciReturnCode_t returnCode; /**< Return code of command */ +} tciResponseHeader_t; + +#endif // TCI_H_ diff --git a/libsecurepath/tlc_communication.cpp b/libsecurepath/tlc_communication.cpp new file mode 100644 index 0000000..1f6636a --- /dev/null +++ b/libsecurepath/tlc_communication.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2012 Samsung Electronics Co., LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "tlc_communication.h" + +#define LOG_TAG "tlc_communication" +#include "log.h" + +mcResult_t tlc_open(mc_comm_ctx *comm_ctx) { + mcResult_t mcRet; + + LOG_I("open() called"); + do { + // ------------------------------------------------------------- + // Step 1: Open the MobiCore device + LOG_I("Opening MobiCore device"); + mcRet = mcOpenDevice(comm_ctx->device_id); + if (MC_DRV_OK != mcRet) + LOG_I("mcOpenDevice result: %d", mcRet); + + + // ------------------------------------------------------------- + // Step 2: Allocate WSM buffer for the TCI + LOG_I("Allocating WSM for TCI"); + mcRet = mcMallocWsm(comm_ctx->device_id, 0, sizeof(tciMessage_t), (uint8_t **)&(comm_ctx->tci_msg), 0); + if (MC_DRV_OK != mcRet) { + LOG_E("Allocation of TCI WSM failed: %d", mcRet); + break; + } + + // ------------------------------------------------------------- + // Step 3: Open session with the Trustlet + LOG_I("Opening the session"); + bzero(&(comm_ctx->handle), sizeof(mcSessionHandle_t)); // Clear the session handle + + comm_ctx->handle.deviceId = comm_ctx->device_id; // The device ID (default device is used) + + mcRet = mcOpenSession(&(comm_ctx->handle), &(comm_ctx->uuid), (uint8_t *)(comm_ctx->tci_msg), + (uint32_t) sizeof(tciMessage_t)); + if (MC_DRV_OK != mcRet) { + LOG_E("Open session failed: %d", mcRet); + break; + } + + LOG_I("tlc_open() succeeded"); + } while (false); + + return mcRet; +} + +mcResult_t tlc_close(mc_comm_ctx *comm_ctx) { + mcResult_t mcRet; + + LOG_I("close() called"); + do { + + // ------------------------------------------------------------- + // Step 1: Free WSM + LOG_I("Free WSM"); + mcRet = mcFreeWsm((comm_ctx->device_id), (uint8_t *)(comm_ctx->tci_msg)); + if (MC_DRV_OK != mcRet) { + LOG_E("Free WSM failed: %d", mcRet); + break; + } + + // ------------------------------------------------------------- + // Step 2: Close session with the Trustlet + LOG_I("Closing the session"); + mcRet = mcCloseSession(&(comm_ctx->handle)); + if (MC_DRV_OK != mcRet) { + LOG_E("Closing session failed: %d", mcRet); + break; + } + + // ------------------------------------------------------------- + // Step 3: Close the MobiCore device + LOG_I("Closing MobiCore device"); + mcRet = mcCloseDevice(comm_ctx->device_id); + if (MC_DRV_OK != mcRet) { + LOG_E("Closing MobiCore device failed: %d", mcRet); + break; + } + + LOG_I("tlc_close() succeeded"); + } while (false); + + return mcRet; +} + +mcResult_t tlc_communicate(mc_comm_ctx *comm_ctx) { + mcResult_t mcRet; + + do { + // ------------------------------------------------------------- + // Step 1: signal the Trustlet + mcRet = mcNotify(&(comm_ctx->handle)); + if (MC_DRV_OK != mcRet) { + LOG_E("Notify failed: %d", mcRet); + break; + } + LOG_I("mcNotify is completed\n"); + + // ------------------------------------------------------------- + // Step 2: Wait for the Trustlet response + mcRet = mcWaitNotification(&(comm_ctx->handle), -1); + if (MC_DRV_OK != mcRet) { + LOG_E("Wait for response notification failed: %d", mcRet); + break; + } + + LOG_I("mcWaitNotification is completed"); + + } while (false); + + return mcRet; +} diff --git a/libsecurepath/tlc_communication.h b/libsecurepath/tlc_communication.h new file mode 100644 index 0000000..8b06b04 --- /dev/null +++ b/libsecurepath/tlc_communication.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2012 Samsung Electronics Co., LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef TLC_COMMUNICATION_H_ +#define TLC_COMMUNICATION_H_ + + +#include "MobiCoreDriverApi.h" + +#include "tlwvdrm_api.h" + +typedef struct { + uint32_t device_id; + mcUuid_t uuid; + mcSessionHandle_t handle; + tciMessage_t *tci_msg; + bool initialized; +} mc_comm_ctx; + +mcResult_t tlc_open(mc_comm_ctx *comm_ctx); +mcResult_t tlc_close(mc_comm_ctx *comm_ctx); +mcResult_t tlc_communicate(mc_comm_ctx *comm_ctx); + + +#endif diff --git a/libsecurepath/tlwvdrm_api.h b/libsecurepath/tlwvdrm_api.h new file mode 100644 index 0000000..04edc61 --- /dev/null +++ b/libsecurepath/tlwvdrm_api.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2012 Samsung Electronics Co., LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TLWVDRM_API_H_ +#define TLWVDRM_API_H_ + +#include "tci.h" + +/** + * Command ID's for communication Trustlet Connector -> Trustlet. + */ +#define CMD_WV_DRM_ENABLE_PATH_PROTECTION 0x00010000 +#define CMD_WV_DRM_DISABLE_PATH_PROTECTION 0x00010001 + + +/** + * Return codes + */ +#define RET_TL_WV_DRM_OK 0x00000000 + +/** + * Error codes + */ +#define RET_ERR_WV_DRM_PROTECT_CONTENT_PATH_INIT 0x00001000 +#define RET_ERR_WV_DRM_PROTECT_CONTENT_PATH_TERM 0x00001001 + + +/** + * Maximum data length. + */ +#define MAX_DATA_LEN 512 + +/** + * TCI message data. + */ + +typedef struct { + uint32_t id; + uint32_t data_len; + uint8_t *data_ptr; + uint8_t data[MAX_DATA_LEN]; +} tci_cmd_t; + +typedef struct { + uint32_t id; + uint32_t return_code; + uint32_t data_len; + uint8_t *data_ptr; + uint8_t data[MAX_DATA_LEN]; +} tci_resp_t; + +typedef struct { + union { + tci_cmd_t cmd; /**< Command message structure */ + tci_resp_t resp; /**< Response message structure */ + }; +} tciMessage_t; + +/** + * Trustlet UUID. + */ +#define TL_WV_DRM_UUID { { 0, 6, 3, 8, 6, 5, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0 } } + +#endif /* TLWVDRM_API_H_ */ -- 2.20.1