Add public signing module for osp-security-service
[framework/osp/security-service.git] / src / TrustZoneService.cpp
1 //
2 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
3 //
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
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
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.
15 //
16
17 /**
18  * @file                TrustZoneService.cpp
19  * @brief               This is the implementation file for TrustZoneService class.
20  */
21
22 #include <new>
23 #include <stdio.h>
24 #include <unique_ptr.h> 
25 #include <SecTzSvc.h>
26 #include <FIo_IpcServer.h>
27 #include <FIo_IIpcServerEventListener.h>
28 #include <FIo_IpcCommonDataTypes.h>
29 #include <FBaseLog.h>
30 #include <FAppPkg_PackageInfoImpl.h>
31 #include <FBase_StringConverter.h>
32 #include <FSec_DeviceKeyGenerator.h>
33 #include <FSecCrypto_TrustZoneServiceMessage.h>
34
35 #include "TrustZoneService.h"
36
37 using namespace Tizen::Base;
38 using namespace Tizen::App;
39 using namespace Tizen::Io;
40 using namespace Tizen::Security;
41
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;
47
48
49 TrustZoneService::TrustZoneService(void)
50         : __pIpcServer(null)
51 {
52
53 }
54
55 TrustZoneService::~TrustZoneService(void)
56 {
57         delete __pIpcServer;
58 }
59
60
61 result
62 TrustZoneService::Construct(void)
63 {
64         result r = E_SUCCESS;
65
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.");
68
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.");
71
72         return r;
73 }
74
75 void
76 TrustZoneService::OnIpcServerStarted(const _IpcServer& server)
77 {
78
79 }
80
81 void
82 TrustZoneService::OnIpcServerStopped(const _IpcServer& server)
83 {
84
85 }
86
87 void
88 TrustZoneService::OnIpcClientConnected(const _IpcServer& server, int clientId)
89 {
90
91 }
92
93 void
94 TrustZoneService::OnIpcClientDisconnected(const _IpcServer&server, int clientId)
95 {
96
97 }
98
99 int 
100 TrustZoneService::SetPadding(const byte* pData, int dataLen, byte** ppOutData, int* outLen)
101 {
102         result r = E_SUCCESS;
103         int paddingSize = 0;
104         std::unique_ptr <byte[]> pOutput;
105
106 #ifdef _TRUST_ZONE_
107         if(dataLen % TRUST_ZONE_CHUNK_LEN == 0)
108         {
109                 paddingSize = 0;
110         }
111         else
112         {
113                 paddingSize = TRUST_ZONE_CHUNK_LEN - (dataLen % TRUST_ZONE_CHUNK_LEN);
114         }
115 #else
116         if(dataLen % AES_CIPHER_BLCOK_LEN == 0)
117         {
118                 paddingSize = 0;
119         }
120         else
121         {
122                 paddingSize = AES_CIPHER_BLCOK_LEN - (dataLen % AES_CIPHER_BLCOK_LEN);
123         }
124 #endif
125
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.");
129         
130         memcpy(pOutput.get(), pData, dataLen);
131         if(paddingSize != 0)
132                 memset(pOutput.get() + dataLen, 0, paddingSize);
133         *ppOutData = pOutput.release();
134
135         SetLastResult(r);
136         return paddingSize;
137 }
138
139 result
140 TrustZoneService::Encrypt(const ByteBuffer& appInfo, const ByteBuffer& plainBuffer, byte** ppBuffer, int& bufferSize)
141 {
142         result r = E_SUCCESS;
143         int tzResult = 0;
144         int encryptedSize = 0;
145         int wrapAppInfoLen = 0;
146         int tempDataLen = 0;
147         int paddingSize = 0;
148         byte* pData = null;
149         byte* pTempData = null;
150         byte* pAppInfo = null;
151         byte* pOutput = null;
152         
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.");
155         
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.");
158
159         paddingSize = SetPadding(pData, plainBuffer.GetRemaining(), &pTempData, &tempDataLen);
160         r = GetLastResult();
161         TryReturnResult(r == E_SUCCESS, r, r, "[%s] Failed to set padding.", GetErrorMessage(r));
162
163         encryptedSize  = SecGetCipherLen(tempDataLen);
164         TryReturnResult(encryptedSize != 0, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Trust Zone error occurred. ");
165         
166         byte encryptedData[encryptedSize];
167         memset(encryptedData, 0, encryptedSize);
168 #ifdef _TRUST_ZONE_
169         wrapAppInfoLen = SecGetCipherLen(TRUST_ZONE_HASH_LEN);
170 #else
171         wrapAppInfoLen = NON_TRUST_ZONE_HASH_LEN;
172 #endif
173         byte wrapAppInfo[wrapAppInfoLen];
174         memset(wrapAppInfo, 0, wrapAppInfoLen);
175
176         tzResult =  SecEncryptTZCrypt(pTempData, tempDataLen, encryptedData, reinterpret_cast<TZCRYPT_UINT32*>(&encryptedSize), pAppInfo, appInfo.GetRemaining(), wrapAppInfo, reinterpret_cast<TZCRYPT_UINT32*>(&wrapAppInfoLen));   
177         delete[] pTempData;
178         TryReturnResult(tzResult == 0, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to encrypt data (error code = %d). ", tzResult);
179
180         pOutput = new (std::nothrow) byte[wrapAppInfoLen + encryptedSize + sizeof(int)];
181
182         memcpy(pOutput, &paddingSize, sizeof(int));
183         memcpy(pOutput + sizeof(int), wrapAppInfo, wrapAppInfoLen);
184         memcpy(pOutput + sizeof(int) + wrapAppInfoLen, encryptedData, encryptedSize);
185
186         *ppBuffer = pOutput;
187         bufferSize = wrapAppInfoLen + encryptedSize + sizeof(int);
188
189         return r;
190 }
191
192 result
193 TrustZoneService::Decrypt(const ByteBuffer& appInfo, const ByteBuffer& encryptedBuffer, byte** ppBuffer, int& bufferSize)
194 {
195         result r = E_SUCCESS;
196         int tzResult = 0;
197         int decryptedSize = 0;
198         int encryptedSize = 0;
199         int wrapAppInfoLen = 0;
200         int paddingSize = 0;
201         byte* pData = null;
202         byte* pAppInfo = null;
203         byte* pOutput = null;
204         
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.");
207         
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.");
210         
211 #ifdef _TRUST_ZONE_
212         wrapAppInfoLen = SecGetCipherLen(TRUST_ZONE_HASH_LEN);
213 #else
214         wrapAppInfoLen = NON_TRUST_ZONE_HASH_LEN;
215 #endif
216
217         memcpy(&paddingSize, pData, sizeof(int));
218         byte wrapAppInfo[wrapAppInfoLen];
219         memcpy(wrapAppInfo, pData + sizeof(int), wrapAppInfoLen);
220
221         encryptedSize = encryptedBuffer.GetRemaining()-wrapAppInfoLen-sizeof(int);
222 #ifdef _TRUST_ZONE_
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);
224 #else 
225         TryReturnResult(encryptedSize > 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Input data (encrypted size = %d) should be valid.", encryptedSize);
226 #endif
227         decryptedSize = encryptedSize;
228         byte decryptedData[decryptedSize];
229         memset(decryptedData, 0, decryptedSize);
230
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);
234
235         pOutput = new (std::nothrow) byte[decryptedSize - paddingSize];
236
237         memcpy(pOutput, decryptedData, decryptedSize-paddingSize);
238
239         *ppBuffer = pOutput;
240         bufferSize = decryptedSize-paddingSize;
241
242         return r;
243 }
244
245 bool
246 TrustZoneService::OnEncrypt(const ByteBuffer& appInfo, const ByteBuffer& plainBuffer, _IpcBuffer* ipcBuffer, result *pRes)
247 {
248         byte* pBuffer = null;
249         int bufferSize = 0;
250
251         *pRes = Encrypt(appInfo, plainBuffer, &pBuffer, bufferSize);
252         ipcBuffer->pBuffer = static_cast<void*>(pBuffer);
253         ipcBuffer->size = bufferSize;
254
255         return true;
256 }
257
258 bool
259 TrustZoneService::OnDecrypt(const ByteBuffer& appInfo, const ByteBuffer& encryptedBuffer, _IpcBuffer* ipcBuffer, result *pRes)
260 {
261         byte* pBuffer = null;
262         int bufferSize = 0;
263
264         *pRes = Decrypt(appInfo, encryptedBuffer, &pBuffer, bufferSize);
265         ipcBuffer->pBuffer = static_cast<void*>(pBuffer);
266         ipcBuffer->size = bufferSize;
267         
268         return true;
269 }
270
271 void
272 TrustZoneService::OnIpcRequestReceived(_IpcServer& server, const IPC::Message& message)
273 {
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()
278 }
279