2 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 * @file TrustZoneService.cpp
19 * @brief This is the implementation file for TrustZoneService class.
24 #include <unique_ptr.h>
26 #include <FIo_IpcServer.h>
27 #include <FIo_IIpcServerEventListener.h>
28 #include <FIo_IpcCommonDataTypes.h>
30 #include <FAppPkg_PackageInfoImpl.h>
31 #include <FBase_StringConverter.h>
32 #include <FSec_DeviceKeyGenerator.h>
33 #include <FSecCrypto_TrustZoneServiceMessage.h>
35 #include "TrustZoneService.h"
37 using namespace Tizen::Base;
38 using namespace Tizen::App;
39 using namespace Tizen::Io;
40 using namespace Tizen::Security;
42 static const int TRUST_ZONE_HASH_LEN = 32;
43 static const int NON_TRUST_ZONE_HASH_LEN = 20;
44 static const int TRUST_ZONE_CHUNK_LEN = 1024;
45 static const int TRUST_ZONE_CIPHER_BLOCK_LEN = 1116;
46 static const int AES_CIPHER_BLCOK_LEN = 16;
49 TrustZoneService::TrustZoneService(void)
55 TrustZoneService::~TrustZoneService(void)
62 TrustZoneService::Construct(void)
66 __pIpcServer = new (std::nothrow) _IpcServer();
67 TryReturnResult(__pIpcServer != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
69 r = __pIpcServer->Construct("osp.security.ipcserver.trustzoneservice", *this);
70 TryReturnResult(r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
76 TrustZoneService::OnIpcServerStarted(const _IpcServer& server)
82 TrustZoneService::OnIpcServerStopped(const _IpcServer& server)
88 TrustZoneService::OnIpcClientConnected(const _IpcServer& server, int clientId)
94 TrustZoneService::OnIpcClientDisconnected(const _IpcServer&server, int clientId)
100 TrustZoneService::SetPadding(const byte* pData, int dataLen, byte** ppOutData, int* outLen)
102 result r = E_SUCCESS;
104 std::unique_ptr <byte[]> pOutput;
107 if(dataLen % TRUST_ZONE_CHUNK_LEN == 0)
113 paddingSize = TRUST_ZONE_CHUNK_LEN - (dataLen % TRUST_ZONE_CHUNK_LEN);
116 if(dataLen % AES_CIPHER_BLCOK_LEN == 0)
122 paddingSize = AES_CIPHER_BLCOK_LEN - (dataLen % AES_CIPHER_BLCOK_LEN);
126 *outLen = paddingSize + dataLen;
127 pOutput = std::unique_ptr <byte[]> (new (std::nothrow) byte[dataLen + paddingSize]);
128 TryReturnResult(pOutput != null, 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Allocating new byte array failed.");
130 memcpy(pOutput.get(), pData, dataLen);
132 memset(pOutput.get() + dataLen, 0, paddingSize);
133 *ppOutData = pOutput.release();
140 TrustZoneService::Encrypt(const ByteBuffer& appInfo, const ByteBuffer& plainBuffer, byte** ppBuffer, int& bufferSize)
142 result r = E_SUCCESS;
144 int encryptedSize = 0;
145 int wrapAppInfoLen = 0;
149 byte* pTempData = null;
150 byte* pAppInfo = null;
151 byte* pOutput = null;
153 pData = const_cast< byte* >(plainBuffer.GetPointer());
154 TryReturnResult(pData != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Input data should be valid.");
156 pAppInfo = const_cast< byte* >(appInfo.GetPointer());
157 TryReturnResult(pAppInfo != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Input data should be valid.");
159 paddingSize = SetPadding(pData, plainBuffer.GetRemaining(), &pTempData, &tempDataLen);
161 TryReturnResult(r == E_SUCCESS, r, r, "[%s] Failed to set padding.", GetErrorMessage(r));
163 encryptedSize = SecGetCipherLen(tempDataLen);
164 TryReturnResult(encryptedSize != 0, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Trust Zone error occurred. ");
166 byte encryptedData[encryptedSize];
167 memset(encryptedData, 0, encryptedSize);
169 wrapAppInfoLen = SecGetCipherLen(TRUST_ZONE_HASH_LEN);
171 wrapAppInfoLen = NON_TRUST_ZONE_HASH_LEN;
173 byte wrapAppInfo[wrapAppInfoLen];
174 memset(wrapAppInfo, 0, wrapAppInfoLen);
176 tzResult = SecEncryptTZCrypt(pTempData, tempDataLen, encryptedData, reinterpret_cast<TZCRYPT_UINT32*>(&encryptedSize), pAppInfo, appInfo.GetRemaining(), wrapAppInfo, reinterpret_cast<TZCRYPT_UINT32*>(&wrapAppInfoLen));
178 TryReturnResult(tzResult == 0, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to encrypt data (error code = %d). ", tzResult);
180 pOutput = new (std::nothrow) byte[wrapAppInfoLen + encryptedSize + sizeof(int)];
182 memcpy(pOutput, &paddingSize, sizeof(int));
183 memcpy(pOutput + sizeof(int), wrapAppInfo, wrapAppInfoLen);
184 memcpy(pOutput + sizeof(int) + wrapAppInfoLen, encryptedData, encryptedSize);
187 bufferSize = wrapAppInfoLen + encryptedSize + sizeof(int);
193 TrustZoneService::Decrypt(const ByteBuffer& appInfo, const ByteBuffer& encryptedBuffer, byte** ppBuffer, int& bufferSize)
195 result r = E_SUCCESS;
197 int decryptedSize = 0;
198 int encryptedSize = 0;
199 int wrapAppInfoLen = 0;
202 byte* pAppInfo = null;
203 byte* pOutput = null;
205 pData = const_cast< byte* >(encryptedBuffer.GetPointer());
206 TryReturnResult(pData != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Input data should be valid.");
208 pAppInfo = const_cast< byte* >(appInfo.GetPointer());
209 TryReturnResult(pAppInfo != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Input data should be valid.");
212 wrapAppInfoLen = SecGetCipherLen(TRUST_ZONE_HASH_LEN);
214 wrapAppInfoLen = NON_TRUST_ZONE_HASH_LEN;
217 memcpy(&paddingSize, pData, sizeof(int));
218 byte wrapAppInfo[wrapAppInfoLen];
219 memcpy(wrapAppInfo, pData + sizeof(int), wrapAppInfoLen);
221 encryptedSize = encryptedBuffer.GetRemaining()-wrapAppInfoLen-sizeof(int);
223 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);
225 TryReturnResult(encryptedSize > 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Input data (encrypted size = %d) should be valid.", encryptedSize);
227 decryptedSize = encryptedSize;
228 byte decryptedData[decryptedSize];
229 memset(decryptedData, 0, decryptedSize);
231 tzResult = SecDecryptTZCrypt(pData+wrapAppInfoLen+sizeof(int), encryptedSize, decryptedData, reinterpret_cast<TZCRYPT_UINT32*>(&decryptedSize), \
232 pAppInfo, appInfo.GetRemaining(), wrapAppInfo, static_cast<TZCRYPT_UINT32>(wrapAppInfoLen));
233 TryReturnResult(tzResult == 0, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to decrypt data (error code = %d)", tzResult);
235 pOutput = new (std::nothrow) byte[decryptedSize - paddingSize];
237 memcpy(pOutput, decryptedData, decryptedSize-paddingSize);
240 bufferSize = decryptedSize-paddingSize;
246 TrustZoneService::OnEncrypt(const ByteBuffer& appInfo, const ByteBuffer& plainBuffer, _IpcBuffer* ipcBuffer, result *pRes)
248 byte* pBuffer = null;
251 *pRes = Encrypt(appInfo, plainBuffer, &pBuffer, bufferSize);
252 ipcBuffer->pBuffer = static_cast<void*>(pBuffer);
253 ipcBuffer->size = bufferSize;
259 TrustZoneService::OnDecrypt(const ByteBuffer& appInfo, const ByteBuffer& encryptedBuffer, _IpcBuffer* ipcBuffer, result *pRes)
261 byte* pBuffer = null;
264 *pRes = Decrypt(appInfo, encryptedBuffer, &pBuffer, bufferSize);
265 ipcBuffer->pBuffer = static_cast<void*>(pBuffer);
266 ipcBuffer->size = bufferSize;
272 TrustZoneService::OnIpcRequestReceived(_IpcServer& server, const IPC::Message& message)
274 IPC_BEGIN_MESSAGE_MAP(TrustZoneService, message)
275 IPC_MESSAGE_HANDLER(TrustZoneService_Encrypt, OnEncrypt, &server)
276 IPC_MESSAGE_HANDLER(TrustZoneService_Decrypt, OnDecrypt, &server)
277 IPC_END_MESSAGE_MAP()