-//
-// Copyright (c) 2012-2013 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.
-//
-
-/**
- * @file TrustZoneService.cpp
- * @brief This is the implementation file for TrustZoneService class.
- */
-
-#include <new>
-#include <stdio.h>
-#include <unique_ptr.h>
-#include <SecTzSvc.h>
-#include <FIo_IpcServer.h>
-#include <FIo_IIpcServerEventListener.h>
-#include <FIo_IpcCommonDataTypes.h>
-#include <FBaseLog.h>
-#include <FAppPkg_PackageInfoImpl.h>
-#include <FBase_StringConverter.h>
-#include <FSec_DeviceKeyGenerator.h>
-#include <FSecCrypto_TrustZoneServiceMessage.h>
-
-#include "TrustZoneService.h"
-
-using namespace Tizen::Base;
-using namespace Tizen::App;
-using namespace Tizen::Io;
-using namespace Tizen::Security;
-
-static const int TRUST_ZONE_HASH_LEN = 32;
-static const int NON_TRUST_ZONE_HASH_LEN = 20;
-static const int TRUST_ZONE_CHUNK_LEN = 1024;
-static const int TRUST_ZONE_CIPHER_BLOCK_LEN = 1116;
-static const int AES_CIPHER_BLCOK_LEN = 16;
-
-
-TrustZoneService::TrustZoneService(void)
- : __pIpcServer(null)
-{
-
-}
-
-TrustZoneService::~TrustZoneService(void)
-{
- delete __pIpcServer;
-}
-
-
-result
-TrustZoneService::Construct(void)
-{
- result r = E_SUCCESS;
-
- __pIpcServer = new (std::nothrow) _IpcServer();
- TryReturnResult(__pIpcServer != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
-
- r = __pIpcServer->Construct("osp.security.ipcserver.trustzoneservice", *this);
- TryReturnResult(r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
-
- return r;
-}
-
-void
-TrustZoneService::OnIpcServerStarted(const _IpcServer& server)
-{
-
-}
-
-void
-TrustZoneService::OnIpcServerStopped(const _IpcServer& server)
-{
-
-}
-
-void
-TrustZoneService::OnIpcClientConnected(const _IpcServer& server, int clientId)
-{
-
-}
-
-void
-TrustZoneService::OnIpcClientDisconnected(const _IpcServer&server, int clientId)
-{
-
-}
-
-int
-TrustZoneService::SetPadding(const byte* pData, int dataLen, byte** ppOutData, int* outLen)
-{
- result r = E_SUCCESS;
- int paddingSize = 0;
- std::unique_ptr <byte[]> pOutput;
-
-#ifdef _TRUST_ZONE_
- if(dataLen % TRUST_ZONE_CHUNK_LEN == 0)
- {
- paddingSize = 0;
- }
- else
- {
- paddingSize = TRUST_ZONE_CHUNK_LEN - (dataLen % TRUST_ZONE_CHUNK_LEN);
- }
-#else
- if(dataLen % AES_CIPHER_BLCOK_LEN == 0)
- {
- paddingSize = 0;
- }
- else
- {
- paddingSize = AES_CIPHER_BLCOK_LEN - (dataLen % AES_CIPHER_BLCOK_LEN);
- }
-#endif
-
- *outLen = paddingSize + dataLen;
- pOutput = std::unique_ptr <byte[]> (new (std::nothrow) byte[dataLen + paddingSize]);
- TryReturnResult(pOutput != null, 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Allocating new byte array failed.");
-
- memcpy(pOutput.get(), pData, dataLen);
- if(paddingSize != 0)
- memset(pOutput.get() + dataLen, 0, paddingSize);
- *ppOutData = pOutput.release();
-
- SetLastResult(r);
- return paddingSize;
-}
-
-result
-TrustZoneService::Encrypt(const ByteBuffer& appInfo, const ByteBuffer& plainBuffer, byte** ppBuffer, int& bufferSize)
-{
- result r = E_SUCCESS;
- int tzResult = 0;
- int encryptedSize = 0;
- int wrapAppInfoLen = 0;
- int tempDataLen = 0;
- int paddingSize = 0;
- byte* pData = null;
- byte* pTempData = null;
- byte* pAppInfo = null;
- byte* pOutput = null;
-
- pData = const_cast< byte* >(plainBuffer.GetPointer());
- TryReturnResult(pData != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Input data should be valid.");
-
- pAppInfo = const_cast< byte* >(appInfo.GetPointer());
- TryReturnResult(pAppInfo != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Input data should be valid.");
-
- paddingSize = SetPadding(pData, plainBuffer.GetRemaining(), &pTempData, &tempDataLen);
- r = GetLastResult();
- TryReturnResult(r == E_SUCCESS, r, r, "[%s] Failed to set padding.", GetErrorMessage(r));
-
- encryptedSize = SecGetCipherLen(tempDataLen);
- TryReturnResult(encryptedSize != 0, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Trust Zone error occurred. ");
-
- byte encryptedData[encryptedSize];
- memset(encryptedData, 0, encryptedSize);
-#ifdef _TRUST_ZONE_
- wrapAppInfoLen = SecGetCipherLen(TRUST_ZONE_HASH_LEN);
-#else
- wrapAppInfoLen = NON_TRUST_ZONE_HASH_LEN;
-#endif
- byte wrapAppInfo[wrapAppInfoLen];
- memset(wrapAppInfo, 0, wrapAppInfoLen);
-
- tzResult = SecEncryptTZCrypt(pTempData, tempDataLen, encryptedData, reinterpret_cast<TZCRYPT_UINT32*>(&encryptedSize), pAppInfo, appInfo.GetRemaining(), wrapAppInfo, reinterpret_cast<TZCRYPT_UINT32*>(&wrapAppInfoLen));
- delete[] pTempData;
- TryReturnResult(tzResult == 0, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to encrypt data (error code = %d). ", tzResult);
-
- pOutput = new (std::nothrow) byte[wrapAppInfoLen + encryptedSize + sizeof(int)];
-
- memcpy(pOutput, &paddingSize, sizeof(int));
- memcpy(pOutput + sizeof(int), wrapAppInfo, wrapAppInfoLen);
- memcpy(pOutput + sizeof(int) + wrapAppInfoLen, encryptedData, encryptedSize);
-
- *ppBuffer = pOutput;
- bufferSize = wrapAppInfoLen + encryptedSize + sizeof(int);
-
- return r;
-}
-
-result
-TrustZoneService::Decrypt(const ByteBuffer& appInfo, const ByteBuffer& encryptedBuffer, byte** ppBuffer, int& bufferSize)
-{
- result r = E_SUCCESS;
- int tzResult = 0;
- int decryptedSize = 0;
- int encryptedSize = 0;
- int wrapAppInfoLen = 0;
- int paddingSize = 0;
- byte* pData = null;
- byte* pAppInfo = null;
- byte* pOutput = null;
-
- pData = const_cast< byte* >(encryptedBuffer.GetPointer());
- TryReturnResult(pData != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Input data should be valid.");
-
- pAppInfo = const_cast< byte* >(appInfo.GetPointer());
- TryReturnResult(pAppInfo != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Input data should be valid.");
-
-#ifdef _TRUST_ZONE_
- wrapAppInfoLen = SecGetCipherLen(TRUST_ZONE_HASH_LEN);
-#else
- wrapAppInfoLen = NON_TRUST_ZONE_HASH_LEN;
-#endif
-
- memcpy(&paddingSize, pData, sizeof(int));
- byte wrapAppInfo[wrapAppInfoLen];
- memcpy(wrapAppInfo, pData + sizeof(int), wrapAppInfoLen);
-
- encryptedSize = encryptedBuffer.GetRemaining()-wrapAppInfoLen-sizeof(int);
-#ifdef _TRUST_ZONE_
- TryReturnResult((encryptedSize > 0)&&(encryptedSize % TRUST_ZONE_CIPHER_BLOCK_LEN == 0), E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Input data (encrypted size = %d) should be valid.", encryptedSize);
-#else
- TryReturnResult(encryptedSize > 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Input data (encrypted size = %d) should be valid.", encryptedSize);
-#endif
- decryptedSize = encryptedSize;
- byte decryptedData[decryptedSize];
- memset(decryptedData, 0, decryptedSize);
-
- tzResult = SecDecryptTZCrypt(pData+wrapAppInfoLen+sizeof(int), encryptedSize, decryptedData, reinterpret_cast<TZCRYPT_UINT32*>(&decryptedSize), \
- pAppInfo, appInfo.GetRemaining(), wrapAppInfo, static_cast<TZCRYPT_UINT32>(wrapAppInfoLen));
- TryReturnResult(tzResult == 0, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to decrypt data (error code = %d)", tzResult);
-
- pOutput = new (std::nothrow) byte[decryptedSize - paddingSize];
-
- memcpy(pOutput, decryptedData, decryptedSize-paddingSize);
-
- *ppBuffer = pOutput;
- bufferSize = decryptedSize-paddingSize;
-
- return r;
-}
-
-bool
-TrustZoneService::OnEncrypt(const ByteBuffer& appInfo, const ByteBuffer& plainBuffer, _IpcBuffer* ipcBuffer, result *pRes)
-{
- byte* pBuffer = null;
- int bufferSize = 0;
-
- *pRes = Encrypt(appInfo, plainBuffer, &pBuffer, bufferSize);
- ipcBuffer->pBuffer = static_cast<void*>(pBuffer);
- ipcBuffer->size = bufferSize;
-
- return true;
-}
-
-bool
-TrustZoneService::OnDecrypt(const ByteBuffer& appInfo, const ByteBuffer& encryptedBuffer, _IpcBuffer* ipcBuffer, result *pRes)
-{
- byte* pBuffer = null;
- int bufferSize = 0;
-
- *pRes = Decrypt(appInfo, encryptedBuffer, &pBuffer, bufferSize);
- ipcBuffer->pBuffer = static_cast<void*>(pBuffer);
- ipcBuffer->size = bufferSize;
-
- return true;
-}
-
-void
-TrustZoneService::OnIpcRequestReceived(_IpcServer& server, const IPC::Message& message)
-{
- IPC_BEGIN_MESSAGE_MAP(TrustZoneService, message)
- IPC_MESSAGE_HANDLER(TrustZoneService_Encrypt, OnEncrypt, &server)
- IPC_MESSAGE_HANDLER(TrustZoneService_Decrypt, OnDecrypt, &server)
- IPC_END_MESSAGE_MAP()
-}
-