SVACE: HEAP_LEAK, correct size in strncpy
[platform/core/security/tef-simulator.git] / ssflib / dep / swdss / source / secure_file.cpp
1 /**
2  * Copyright (c) 2013-2017 Samsung Electronics Co., Ltd All Rights Reserved
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 #include "ss_crypto.h"
19 #include "secure_file.h"
20 #include <ctype.h>
21 #include "ss_misc.h"
22 #include "OsaLinuxUser.h"
23 #include <new>
24
25 #ifdef _SECOS_SIM_
26 #include "file_op.h"
27 //#define SWD_SS_ROOT "/opt/usr/apps/tz_simulator/data/swdss/"
28 #define SWD_SS_ROOT "/tmp/tastore2/"
29
30 #endif
31
32 #define MAX_FILENAME_LEN 256
33
34 // this is RNG SEED for mask
35 static const CBT_UINT32 RNG_SEED = 0xa3e59cf2;
36 // this is RNG SEED for mask
37 static const CBT_UINT32 RNG_KEY_SEED = 0x3ae19f52;
38
39 // Salts and IDs used i PBKDF2
40 static const CBT_UINT32 SALT_SIZE = 20;
41 //static CBT_UINT32 gUSaltID1 = 0;
42 static const CBT_OCTET USALT1[SALT_SIZE] = {0xa2, 0x40, 0x51, 0x4f, 0x5d, 0x6c,
43     0xc5, 0x4f, 0xb0, 0x3f, 0x53, 0x33, 0xe9, 0x8a, 0xc0, 0xae, 0, 0, 0, 1};
44 //static CBT_UINT32 gUSaltID2 = 0;
45 static const CBT_OCTET USALT2[SALT_SIZE] = {0x0f, 0xb3, 0x9c, 0x0e, 0x65, 0x49,
46     0x91, 0x68, 0xa8, 0xe4, 0xd3, 0xa4, 0xdd, 0xe6, 0x3a, 0x0d, 0, 0, 0, 1};
47
48 //static CBT_UINT32 gCSaltID1 = 0;
49 static const CBT_OCTET CSALT1[SALT_SIZE] = {0x51, 0xa2, 0x40, 0x5d, 0x6c, 0x4f,
50     0xc5, 0xb0, 0x3f, 0x53, 0x4f, 0x33, 0xe9, 0xae, 0x8a, 0xc0, 0, 0, 0, 1};
51 //static CBT_UINT32 gCSaltID2 = 0;
52 static const CBT_OCTET CSALT2[SALT_SIZE] = {0x91, 0xb3, 0x9c, 0xa4, 0x0e, 0x0f,
53     0x49, 0x68, 0xa8, 0xe4, 0xd3, 0x0d, 0x65, 0xdd, 0xe6, 0x3a, 0, 0, 0, 1};
54
55 const unsigned char g_Prekey[] = {0xa1, 0x21, 0x51, 0x71, 0xf1, 0x01, 0xd1,
56     0x31, 0x41, 0x01, 0x01, 0x91, 0x91, 0xb1, 0xe1, 0x11};
57
58 // PBKDF2 iterations count
59 static const CBT_UINT32 PHASE1_ITER = 200;
60 static const CBT_UINT32 PHASE2_ITER = 250;
61
62 #ifndef _SECOS_SIM_
63 /*!
64  *  \brief  Determine file structure index
65  *  \param  pFileHeader [in]  pointer to file header
66  *  \return Structure index
67  */
68 static CBT_UINT32 FileStructureType(CBT_OCTET* pFileHeader) {
69         return (pFileHeader[6] ^ pFileHeader[7]) % 6;
70 }
71 #endif
72
73 static int PBKDF2(const CBT_OCTET* pKeyMaterial, CBT_UINT32 uKeyMaterialSize,
74     const CBT_OCTET* pSalt, unsigned long c, CBT_OCTET* pKey,
75     CryptoAlgorithm alg) {
76
77         CBT_OCTET pU[32] = {0};
78         CBT_OCTET pT[32] = {0};
79         cc_u32 uTSize = 0;
80
81         memcpy(pU, pSalt, SALT_SIZE);
82
83         // preparing crypto conteiner for HMAC-SHA1
84         CryptoCoreContainer *crt = create_CryptoCoreContainer(alg);
85
86         // main cycle
87         for (unsigned long i = 0; i < c; i++) {
88                 crt->MAC_getMAC(crt, const_cast<CBT_OCTET*>(pKeyMaterial), uKeyMaterialSize,
89                     pU, CCryptoEngine::Hash_Size, pT, &uTSize);
90                 memcpy(pU, pT, uTSize);
91         }
92
93         destroy_CryptoCoreContainer(crt);
94
95         memcpy(pKey, pT, CCryptoEngine::Key_Size);
96
97         return 0;
98 }
99
100 static int MDeriveCommonKey1(const CBT_OCTET* pKeyMaterial,
101     CBT_UINT32 uKeyMaterialSize, CBT_OCTET* pKey) {
102         // deriving key
103         PBKDF2(pKeyMaterial, uKeyMaterialSize, CSALT1, PHASE1_ITER, pKey, ID_HSHA1);
104
105         return 0;
106 }
107
108 static int MDeriveCommonKey2(const CBT_OCTET* pKeyMaterial,
109     CBT_UINT32 uKeyMaterialSize, CBT_OCTET* pKey) {
110         // deriving key
111         PBKDF2(pKeyMaterial, uKeyMaterialSize, CSALT2, PHASE2_ITER, pKey, ID_HSHA1);
112
113         return 0;
114 }
115
116 static int MDeriveUniqueKey1(const CBT_OCTET* pKeyMaterial,
117     CBT_UINT32 uKeyMaterialSize, CBT_OCTET* pKey) {
118         // deriving key
119         PBKDF2(pKeyMaterial, uKeyMaterialSize, USALT1, PHASE1_ITER, pKey, ID_HSHA1);
120
121         return 0;
122 }
123
124 static int MDeriveUniqueKey2(const CBT_OCTET* pKeyMaterial,
125     CBT_UINT32 uKeyMaterialSize, CBT_OCTET* pKey) {
126         unsigned long nSize = 0;
127         CBT_OCTET* pBuffer = (CBT_OCTET*)NULL;
128         CBT_OCTET key[16] = {0, };
129
130         if (uKeyMaterialSize > KEY_MAT_SIZE) {
131                 SLOGE("uKeyMaterialSize %d is too big.\n", uKeyMaterialSize);
132                 return SS_RET_INTERNAL_ERROR;
133         }
134
135         pBuffer = new(std::nothrow) CBT_OCTET[uKeyMaterialSize + 16];
136         if (!pBuffer) {
137                 SLOGE("Alloc memory failed.\n");
138                 return SS_RET_MALLOC_FAILED;
139         }
140
141         memset(pBuffer, 0, uKeyMaterialSize + 16);
142
143 #if defined(_SECOS_SIM_)
144 #define UCI_HW_SECRET_KEY 0
145 #define ID_UCI_ENC_ECB 0
146 #endif
147
148         int iRet = CCryptoEngine::HWEncrypt(pBuffer, &nSize, (CBT_OCTET*)pKeyMaterial,
149             uKeyMaterialSize, key,
150             UCI_HW_SECRET_KEY,
151             ID_UCI_ENC_ECB);
152         if (iRet) {
153                 SLOGE("Failed to do HWEncrypt, ret_code %d.\n", iRet);
154                 delete[] pBuffer;
155                 return SS_RET_INTERNAL_ERROR;
156         }
157
158         memset(pBuffer + CCryptoEngine::Key_Size, 0, 16); //hack
159
160         // deriving key
161         PBKDF2(pBuffer, nSize, USALT2, PHASE2_ITER, pKey, ID_HSHA1);
162
163         delete[] pBuffer;
164
165         return 0;
166 }
167
168 static int GenKey(const CBT_OCTET* pKeyMaterial, CBT_OCTET* pKey,
169     CBT_UINT32 options) {
170         int iRet = 0;
171         CBT_OCTET pBufKey[CCryptoEngine::Key_Size];
172
173         // performing first transformation
174         if (options & SS_OPT_COMMON) {
175                 iRet = MDeriveCommonKey1(pKeyMaterial, KEY_MAT_SIZE, pBufKey);
176         } else {
177                 iRet = MDeriveUniqueKey1(pKeyMaterial, KEY_MAT_SIZE, pBufKey);
178         }
179
180         if (iRet) {
181                 SLOGE("Failed to derive key 1st phase.\n");
182                 return SS_RET_INTERNAL_ERROR;
183         }
184
185         // performing second transformation
186         if (options & SS_OPT_COMMON) {
187                 iRet = MDeriveCommonKey2(pBufKey, CCryptoEngine::Key_Size, pKey);
188         } else {
189                 iRet = MDeriveUniqueKey2(pBufKey, CCryptoEngine::Key_Size, pKey);
190         }
191
192         if (iRet) {
193                 SLOGE("Failed to derive key 2nd phase.\n");
194                 return SS_RET_INTERNAL_ERROR;
195         }
196
197         return iRet;
198 }
199
200 int Encrypt(uint8_t* dest, uint8_t* src, unsigned long data_len,
201     uint8_t* key_material, uint32_t options) {
202         int iRet = 0;
203         CBT_OCTET pKey[CCryptoEngine::Key_Size];
204
205         // generating random key data
206         CCryptoEngine::Random(key_material, KEY_MAT_SIZE);
207
208         iRet = GenKey(key_material, pKey, options);
209         if (iRet) {
210                 SLOGE("Failed to do MGenKey.\n");
211                 return 0;
212         }
213
214         return CCryptoEngine::Encrypt(dest, src, data_len, pKey, 0);
215 }
216
217 int EncryptEx(uint8_t* dest, uint8_t* src, unsigned long data_len,
218     uint8_t* key_material, uint8_t* enc_key, uint32_t options) {
219         CBT_OCTET pKey[CCryptoEngine::Key_Size];
220
221         int iRet = 0;
222         //int i;
223         int ret;
224         // generating random key data
225         CCryptoEngine::Random(key_material, KEY_MAT_SIZE);
226
227         iRet = GenKey(key_material, pKey, options);
228         if (iRet) {
229                 SLOGE("Failed to do MGenKey.\n");
230                 return 0;
231         }
232
233         unsigned int cipherTextLen, t;
234         CryptoCoreContainer *crt = create_CryptoCoreContainer(ID_AES);
235
236         if (crt == NULL) {
237                 return 0;
238         }
239         crt->SE_init(crt, ID_ENC_ECB, ID_NO_PADDING, const_cast<uint8_t*>(g_Prekey),
240             CCryptoEngine::Key_Size, (cc_u8*)NULL);
241         crt->SE_process(crt, pKey, CCryptoEngine::Key_Size, enc_key,
242             static_cast<cc_u32*>(&cipherTextLen));
243         crt->SE_final(crt, (cc_u8*)NULL, 0, (pKey + cipherTextLen),
244             static_cast<cc_u32*>(&t));
245         cipherTextLen += t;
246         destroy_CryptoCoreContainer(crt);
247
248         ret = CCryptoEngine::Encrypt(dest, src, data_len, pKey, 0);
249
250         return ret;
251 }
252
253 int Decrypt(uint8_t* dest, uint8_t* src, unsigned long data_len,
254     const uint8_t* key_material, uint32_t options) {
255         int iRet = 0;
256         CBT_OCTET pKey[CCryptoEngine::Key_Size];
257
258         if (key_material == 0) {
259                 SLOGE("Key material is NULL.\n");
260                 return 0;
261         }
262
263         iRet = GenKey(key_material, pKey, options);
264         if (iRet) {
265                 SLOGE("Failed to do MGenKey.\n");
266                 return 0;
267         }
268
269         return CCryptoEngine::Decrypt(dest, src, data_len, pKey, 0);
270 }
271
272 int DecryptEx(uint8_t* dest, uint8_t* src, unsigned long data_len,
273     const uint8_t* enc_key/*, uint32_t keysize,  uint8_t* rsa_n_data, uint32_t rsa_n_len, uint8_t* rsa_d_data, uint32_t rsa_d_len*/) {
274         int ret;
275         //int i;
276         //unsigned long uDecryptedKeySize;
277         uint8_t decryptedKeyBuffer[ENCRYPTED_KEY_SIZE];
278
279         unsigned int plainTextLen, t;
280         CryptoCoreContainer *crt = create_CryptoCoreContainer(ID_AES);
281         if (crt == NULL) {
282                 return 0;
283         }
284
285         crt->SE_init(crt, ID_DEC_ECB, ID_NO_PADDING, const_cast<uint8_t*>(g_Prekey),
286             16, (cc_u8*)NULL);
287         crt->SE_process(crt, const_cast<uint8_t*>(enc_key), CCryptoEngine::Key_Size,
288             decryptedKeyBuffer, static_cast<cc_u32*>(&plainTextLen));
289         crt->SE_final(crt, NULL, 0, (uint8_t*)(decryptedKeyBuffer + plainTextLen),
290             static_cast<cc_u32*>(&t));
291         destroy_CryptoCoreContainer(crt);
292         plainTextLen += t;
293
294         ret = CCryptoEngine::Decrypt(dest, src, data_len, decryptedKeyBuffer, 0);
295
296         return ret;
297 }
298
299 int is_valid_credential(const ss_credential_s& cred) {
300         // In its canonical form, a UUID consists of 32 hexadecimal digits, displayed in 5 groups separated by hyphens,
301         // in the form 8-4-4-4-12 for a total of 36 characters(32 digits and 4 '-'). For example:
302         // 550e8400-e29b-41d4-a716-446655440000
303         // Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the version number as well
304         // as two reserved bits. All other bits are set using a random or pseudorandom data source.
305         // Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx with hexadecimal digits x and hexadecimal
306         // digits 8, 9, A, or B for y. e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479.
307         char tmp_uuid[SS_MAX_UUID_LEN + 1] = {0};
308         char tmp_mn[SS_MAX_MODULE_NAME_LEN + 1] = {0};
309         strncpy(tmp_uuid, cred.uuid, SS_MAX_UUID_LEN);
310         strncpy(tmp_mn, cred.module_name, SS_MAX_MODULE_NAME_LEN);
311
312         // we have to check only UUID format
313         // checking size
314         if (strlen(tmp_uuid) != 36) {
315                 return SS_RET_INVALID_CREDENTIAL;
316         }
317         // checking delimiters
318         if (tmp_uuid[8] != '-' || tmp_uuid[13] != '-' || tmp_uuid[18] != '-'
319             || tmp_uuid[23] != '-') {
320                 return SS_RET_INVALID_CREDENTIAL;
321         }
322
323         // checking specific values
324         //if (tmp_uuid[14] != '4' || (tmp_uuid[19] != '8' && tmp_uuid[19] != '9' && tmp_uuid[19] != 'a' && tmp_uuid[19] != 'b'))
325         //{
326         //    return SS_RET_INVALID_CREDENTIAL;
327         //}
328         // checking that string contains only hexidecimal values
329         if (-1 == is_hex(tmp_uuid, '-')) {
330                 return SS_RET_INVALID_CREDENTIAL;
331         }
332
333         // Module name shall not contain any spaces
334         for (uint32_t i = 0; i < strlen(tmp_mn); ++i) {
335                 if (isspace(tmp_mn[i])) {
336                         return SS_RET_INVALID_CREDENTIAL;
337                 }
338         }
339
340         return SS_RET_SUCCESS;
341 }
342
343 static int is_valid_options(unsigned int options) {
344         if (((options & SS_OPT_COMMON) && (options & SS_OPT_UNIQUE))
345             || ((options & SS_OPT_TEMPORARY) && (options & SS_OPT_PERMANENT))) {
346                 return SS_RET_INVALID_OPTIONS;
347         }
348
349         return SS_RET_SUCCESS;
350 }
351
352 static int is_valid_data_name(const char* data_name) {
353         for (int i = 0; data_name[i] != 0; ++i) {
354                 if ((!isalnum(data_name[i])) && ('-' != data_name[i])
355                     && ('_' != data_name[i]) && ('.' != data_name[i])) {
356                         return SS_RET_INVALID_DATA_NAME;
357                 }
358         }
359
360         return SS_RET_SUCCESS;
361 }
362
363 int cred_options_check(const ss_credential_s* cred, unsigned int options) {
364         if (SS_RET_SUCCESS != is_valid_credential(*cred)) {
365                 SLOGE("[%s] invalid credential.\n", __FUNCTION__);
366                 return SS_RET_INVALID_CREDENTIAL;
367         }
368
369         if (SS_RET_SUCCESS != is_valid_options(options)) {
370                 SLOGE("[%s] invalid options.\n", __FUNCTION__);
371                 return SS_RET_INVALID_OPTIONS;
372         }
373
374         return SS_RET_SUCCESS;
375 }
376
377 int secure_file::initialize(const ss_credential_s * cred, const char* data_name,
378     unsigned int options) {
379         int iRet = cred_options_check(cred, options);
380         if (SS_RET_SUCCESS != iRet) {
381                 return iRet;
382         }
383
384         m_cred = *cred;
385
386         m_data_name[0] = '\0';
387         if (NULL != data_name) {
388                 strncpy(m_data_name, data_name, sizeof(m_data_name));
389                 m_data_name[sizeof(m_data_name)-1] = '\0';
390         }
391
392         m_options = options;
393
394         m_use_crypted_key = false;
395
396         m_cache = ss_temp_store::get_instance();
397         if (NULL == m_cache) {
398                 SLOGF("[%s][%d](ERROR) Failed to alloc cache_manager. ", __FUNCTION__,
399                     __LINE__);
400                 return SS_RET_MALLOC_FAILED;
401         }
402
403         return SS_RET_SUCCESS;
404 }
405
406 uint32_t secure_file::transform_name_to_id(const char* data_name) {
407         uint32_t uuidFile = 0;
408
409         for (unsigned int i = 0; i < strlen(data_name); i++) {
410                 uuidFile = uuidFile * 33 + data_name[i];
411         }
412
413         return uuidFile;
414 }
415
416 uint64_t secure_file::transform_id_to_name(uint64_t uDataFileID) {
417         uint64_t uDataFileName;
418         CBT_UINT32 uDataFileName1, uDataFileName2;
419         // the main idea of this function is to transfor initial file id into different number which
420         // hexidecimal representation will be the real file name.
421         // first part
422         seed_rand(uDataFileID & 0xffffffff);
423         uDataFileName1 = gen_rand();
424         uDataFileName1 = (uDataFileName1 << 15) | (uDataFileName1 >> (32 - 15));
425         seed_rand(RNG_SEED);
426         uDataFileName1 ^= gen_rand();
427         // second part
428         seed_rand((uDataFileID >> 32) & 0xffffffff);
429         uDataFileName2 = gen_rand();
430         uDataFileName2 = (uDataFileName2 << 10) | (uDataFileName2 >> (32 - 10));
431         seed_rand(RNG_SEED);
432         uDataFileName2 ^= gen_rand();
433         // hexidecimal representation of return value will be the real file name.
434         uDataFileName = uDataFileName1 | (((uint64_t)uDataFileName2) << 32);
435
436         SLOGI("[%s][%d] uDataFileName : %llu", __FUNCTION__, __LINE__, (unsigned long long)uDataFileName);
437         return uDataFileName;
438 }
439
440 int secure_file::finalize() {
441         if (m_file_content.m_bHeaderAllocated) {
442                 delete[] m_file_content.m_pFileHeader;
443                 m_file_content.m_pFileHeader = NULL;
444                 m_file_content.m_bHeaderAllocated = false;
445         }
446
447         if (m_file_content.m_bHashAllocated) {
448                 delete[] m_file_content.m_pHashMaterial;
449                 m_file_content.m_bHashAllocated = NULL;
450                 m_file_content.m_bHashAllocated = false;
451         }
452
453         if (m_file_content.m_bKeyAllocated) {
454                 delete[] m_file_content.m_pKeyMaterial;
455                 m_file_content.m_pKeyMaterial = NULL;
456                 m_file_content.m_bKeyAllocated = false;
457         }
458
459         if (m_file_content.m_bFileContentAllocated) {
460                 delete[] m_file_content.m_pFileContent;
461                 m_file_content.m_pFileContent = NULL;
462                 m_file_content.m_bFileContentAllocated = false;
463         }
464
465         if (m_file_content.m_pOutputContent) {
466                 delete[] m_file_content.m_pOutputContent;
467                 m_file_content.m_pOutputContent = NULL;
468         }
469
470         if (m_is_partial_write) {
471                 if (NULL != m_write_data) {
472                         OsaFree(m_write_data);
473                 }
474         }
475
476         if (m_read_data) {
477                 OsaFree(m_read_data);
478         }
479
480         // finalize shm mgr
481
482         return SS_RET_SUCCESS;
483 }
484
485 int secure_file::derive_file_path() {
486 #ifdef _SECOS_SIM_
487         if (true == m_file_path_ready) {
488                 return SS_RET_SUCCESS;
489         }
490
491         memcpy(m_full_path, m_cred.uuid, SS_MAX_UUID_LEN);
492         strcat(m_full_path, "/");
493         strcat(m_full_path, m_data_name);
494         m_file_path_ready = true;
495         return SS_RET_SUCCESS;
496 #else
497
498         //std::string sfolder;
499         char sUUID_and_Name[SS_MAX_UUID_LEN + SS_MAX_MODULE_NAME_LEN + 2] = {0};
500         char sTemp[SS_MAX_UUID_LEN + SS_MAX_MODULE_NAME_LEN
501         + 2 * CCryptoEngine::Hash_Size + 2] = {0};
502
503         CBT_OCTET pHash[2 * CCryptoEngine::Hash_Size];
504         CBT_OCTET pFolderName[2 * CCryptoEngine::Hash_Size];
505
506         // combining UUID and Name
507         char tmp_uuid[SS_MAX_UUID_LEN + 1] = {0};
508         char tmp_mn[SS_MAX_MODULE_NAME_LEN + 1] = {0};
509         strncpy(tmp_uuid, m_cred.uuid, SS_MAX_UUID_LEN);
510         strncpy(tmp_mn, m_cred.module_name, SS_MAX_MODULE_NAME_LEN);
511
512         memcpy(sUUID_and_Name, tmp_uuid, strlen(tmp_uuid));
513         memcpy(sUUID_and_Name + strlen(tmp_uuid), tmp_mn, strlen(tmp_mn));
514
515         // compute hash value of sUUID_and_Name
516         CCryptoEngine::Hash(pHash,
517                         (CBT_OCTET*)sUUID_and_Name,
518                         strlen(sUUID_and_Name));
519
520         // obtain first part of our string
521         byte_to_hex(pFolderName, pHash, CCryptoEngine::Hash_Size);
522         memcpy(sTemp, pFolderName, 2 * CCryptoEngine::Hash_Size);
523         //sTemp.assign((char*)pFolderName, 2*CCryptoEngine::Hash_Size);
524
525         // concatenate with UUID and Name
526         //sTemp += sUUID_and_Name;
527         memcpy(sTemp + 2 * CCryptoEngine::Hash_Size,
528                         sUUID_and_Name,
529                         strlen(sUUID_and_Name));
530
531         // compute hash of obtained string
532         CCryptoEngine::Hash(pHash, (CBT_OCTET*)sTemp, strlen(sTemp));
533
534         // we will use first 4 bytes of hash value
535         // convert them into hex format
536         //byte_to_hex(pFolderName, pHash, 4);
537
538         // set folder name
539         //sfolder.assign((char*)pFolderName, 8);
540         //sfolder += "/";
541
542         //m_full_path = sfolder;
543         memset(m_full_path, 0, SS_FULL_DATA_NAME_LEN);
544         memcpy(m_full_path, pHash, 4);
545
546         unsigned char dir[9] = {0};
547         byte_to_hex(dir, pHash, 4);
548         SLOGI("Dir is %s.", (char*)dir);
549
550         //m_full_path[8] = '/';
551
552         if (0 != strlen(m_data_name)) {
553                 // computing file name
554                 uint64_t data_id = transform_id_to_name(transform_name_to_id(m_data_name));
555                 memcpy(&m_full_path[4], &data_id, sizeof(uint64_t));
556
557                 unsigned char filename[17] = {0};
558                 byte_to_hex(filename, (unsigned char*)&m_full_path[4], 8);
559                 SLOGI("filename is %s.", (char*)filename);
560         }
561
562         m_file_path_ready = true;
563
564         return SS_RET_SUCCESS;
565 #endif
566 }
567
568 void secure_file::compute_file_hash(CBT_OCTET* pHash) {
569         CryptoCoreContainer *crt = create_CryptoCoreContainer(ID_SHA1);
570         crt->MD_init(crt);
571         crt->MD_update(crt,
572             static_cast<cc_u8*>((void*)const_cast<uint8_t*>(m_file_content
573                 .m_pFileContent)), m_file_content.m_uFileContentSize);
574         crt->MD_update(crt,
575             static_cast<cc_u8*>((void*)const_cast<uint8_t*>(m_file_content
576                 .m_pKeyMaterial)), m_file_content.m_uKeyMaterialSize);
577         crt->MD_final(crt, (uint8_t*)pHash);
578         destroy_CryptoCoreContainer(crt);
579 }
580
581 int secure_file::prepare_file_content(unsigned char* buffer,
582     unsigned int buf_size) {
583 #ifdef _SECOS_SIM_
584         return 0;
585 #else
586
587         // first of all we have to encrypt file data
588         // allocating enough memory for encrypted content
589         m_file_content.m_pFileContent = new CBT_OCTET[buf_size + 32];
590
591         // allocating anough memory for key material
592         m_file_content.m_pKeyMaterial = new CBT_OCTET[KEY_MAT_SIZE];
593         m_file_content.m_uKeyMaterialSize = KEY_MAT_SIZE;
594         if (!m_file_content.m_pKeyMaterial) {
595                 SLOGD("[%s][%d](SS_RET_MALLOC_FAILED) CAN'T Malloc 'm_file_content.m_pKeyMaterial' to conatin pKey",
596                                 __FUNCTION__,
597                                 __LINE__);
598                 return SS_RET_MALLOC_FAILED;
599         }
600         m_file_content.m_bKeyAllocated = true;
601
602         if (!m_file_content.m_pFileContent) {
603                 SLOGD("[%s][%d](SS_RET_MALLOC_FAILED) CAN'T Malloc 'm_file_content.m_pFileContent' used in Encypt(m_FileContent.m_pFileContent, ..)",
604                                 __FUNCTION__,
605                                 __LINE__);
606                 return SS_RET_MALLOC_FAILED;
607         }
608
609         m_file_content.m_bFileContentAllocated = true;
610
611         if (m_use_crypted_key) {
612                 int ret;
613
614                 long unsigned uEncryptedKeySize;
615                 CBT_OCTET keybuf[CCryptoEngine::Key_Size];
616                 m_file_content.m_uFileContentSize = EncryptEx(m_file_content.m_pFileContent,
617                                 const_cast<CBT_OCTET*>(buffer),
618                                 buf_size,
619                                 m_file_content.m_pKeyMaterial,
620                                 keybuf,
621                                 m_options);
622
623                 if (0 == m_file_content.m_uFileContentSize) {
624                         SLOGD("[%s][%d](ERROR) TZ Can't ENcrypt data WITH EncryptedKey mode. // (0 == m_file_content.m_pOutputContentSize)",
625                                         __FUNCTION__,
626                                         __LINE__);
627                         SLOGF("[%s][%d](ERROR)", __FUNCTION__, __LINE__);
628                         return SS_RET_INTERNAL_ERROR;
629                 }
630
631                 ret = CCryptoEngine::RSAEncrypt(m_file_content.m_EncryptedKeyBuffer + 4,
632                                 &uEncryptedKeySize,
633                                 keybuf,
634                                 CCryptoEngine::Key_Size,
635                                 m_rsa_key.rsa_n_data,
636                                 m_rsa_key.rsa_n_len,
637                                 m_rsa_key.rsa_e_data,
638                                 m_rsa_key.rsa_e_len);
639
640                 // the first 4 bytes of buffer containes encrypted data size
641                 m_file_content.m_EncryptedKeyBuffer[0] = uEncryptedKeySize & 0xff;
642                 m_file_content.m_EncryptedKeyBuffer[1] = (uEncryptedKeySize >> 8) & 0xff;
643                 m_file_content.m_EncryptedKeyBuffer[2] = (uEncryptedKeySize >> 16) & 0xff;
644                 m_file_content.m_EncryptedKeyBuffer[3] = (uEncryptedKeySize >> 24) & 0xff;
645
646                 if (CRYPTO_SUCCESS != ret) {
647                         SLOGD("%s RSA Encryption failure %i\n", __FUNCTION__, ret);
648                         return SS_RET_FAIL;
649                 } else {
650                         SLOGD("%s Content key size is = %ld\n", __FUNCTION__, uEncryptedKeySize);
651                 }
652
653         } else {
654                 m_file_content.m_uFileContentSize = Encrypt(m_file_content.m_pFileContent,
655                                 const_cast<CBT_OCTET*>(buffer),
656                                 buf_size,
657                                 m_file_content.m_pKeyMaterial,
658                                 m_options);
659
660                 if (0 == m_file_content.m_uFileContentSize) {
661                         SLOGD("[%s][%d](ERROR) TZ Can't ENcrypt data WITHOUT EncryptedKey mode. // (0 == m_file_content.m_pOutputContentSize)",
662                                         __FUNCTION__,
663                                         __LINE__);
664                         SLOGF("[%s][%d](ERROR)", __FUNCTION__, __LINE__);
665                         return SS_RET_INTERNAL_ERROR;
666                 }
667         }
668
669         // time to compute hash
670         // allocating anough memory for hash
671         m_file_content.m_pHashMaterial = new CBT_OCTET[HASH_SIZE];
672         m_file_content.m_uHashMaterialSize = HASH_SIZE;
673
674         if (!m_file_content.m_pHashMaterial) {
675                 return SS_RET_MALLOC_FAILED;
676         }
677
678         m_file_content.m_bHashAllocated = true;
679
680         // filling it with random data
681         CCryptoEngine::Random(m_file_content.m_pHashMaterial, HASH_SIZE);
682
683         // computing hash
684         compute_file_hash(m_file_content.m_pHashMaterial);
685
686         // time to make header
687         // allocating anough memory for header
688         m_file_content.m_pFileHeader = new CBT_OCTET[HEADER_SIZE];
689         m_file_content.m_uFileHeaderSize = HEADER_SIZE;
690         if (!m_file_content.m_pFileHeader) {
691                 SLOGD("[%s][%d](SS_RET_MALLOC_FAILED) CAN'T Malloc 'm_file_content.m_pFileHeader' to initialize Header information",
692                                 __FUNCTION__,
693                                 __LINE__);
694                 return SS_RET_MALLOC_FAILED;
695         }
696
697         m_file_content.m_bHeaderAllocated = true;
698
699         // filling it with random data
700         CCryptoEngine::Random(m_file_content.m_pFileHeader, HEADER_SIZE);
701
702         m_file_content.m_pFileHeader[0] = 0xa5;
703         m_file_content.m_pFileHeader[1] = 0x5a;
704         m_file_content.m_pFileHeader[2] = 2;
705         m_file_content.m_pFileHeader[3] = 0;
706         m_file_content.m_pFileHeader[4] = 1;
707
708         if (m_use_crypted_key) {
709                 m_file_content.m_pFileHeader[5] = 1; //encrypted key attached to file
710         } else {
711                 m_file_content.m_pFileHeader[5] = 0;
712         }
713
714         SLOGI("[%s] m_file_content.m_pFileHeader[5] = %i",
715                         __FUNCTION__,
716                         m_file_content.m_pFileHeader[5]);
717
718         return SS_RET_SUCCESS;
719 #endif
720 }
721
722 int secure_file::parse_file_content(unsigned char* buffer,
723     unsigned int buf_size) {
724 #ifdef _SECOS_SIM_
725         return 0;
726 #else
727
728         // header shall be at least 16 bytes.
729         if (NULL == buffer) {
730                 SLOGD("[%s][%d](SS_RET_INVALID_FILE)", __FUNCTION__, __LINE__);
731                 return SS_RET_INVALID_FILE;
732         }
733         // the first 2 bytes shall have fixed values
734         if (buffer[0] != 0xa5 || buffer[1] != 0x5a) {
735                 SLOGD("[%s][%d](SS_RET_INVALID_FILE) *pBuffer : %c // %x",
736                                 __FUNCTION__,
737                                 __LINE__,
738                                 *buffer,
739                                 *buffer);
740                 SLOGD("[%s][%d](SS_RET_INVALID_FILE) *(pBuffer+1) : %c // %x",
741                                 __FUNCTION__,
742                                 __LINE__,
743                                 *(buffer + 1),
744                                 *(buffer + 1));
745                 return SS_RET_INVALID_FILE;
746         }
747
748         // the next 4 bytes containes SS version and file structure version
749         if ((buffer[2] != 2) || (buffer[3] != 0)) {
750                 SLOGD("[%s][%d](SS_RET_INVALID_FILE) *(pBuffer+2) : %c // %x",
751                                 __FUNCTION__,
752                                 __LINE__,
753                                 *(buffer + 2),
754                                 *(buffer + 2));
755                 SLOGD("[%s][%d](SS_RET_INVALID_FILE) *(pBuffer+3) : %c // %x",
756                                 __FUNCTION__,
757                                 __LINE__,
758                                 *(buffer + 3),
759                                 *(buffer + 3));
760                 return SS_RET_INVALID_FILE;
761         }
762
763         if ((buffer[4] != 1) || ((buffer[5] != 0) && (buffer[5] != 1))) {
764                 SLOGD("[%s][%d](SS_RET_INVALID_FILE) *(pBuffer+4) : %c // %x",
765                                 __FUNCTION__,
766                                 __LINE__,
767                                 *(buffer + 4),
768                                 *(buffer + 4));
769                 SLOGD("[%s][%d](SS_RET_INVALID_FILE) *(pBuffer+5) : %c // %x",
770                                 __FUNCTION__,
771                                 __LINE__,
772                                 *(buffer + 5),
773                                 *(buffer + 5));
774                 return SS_RET_INVALID_FILE;
775         }
776
777         // temporary pointer to file content
778         CBT_OCTET* ptr = const_cast<CBT_OCTET*>(buffer);
779
780         // header, key material and hash sizes are fixed
781         m_file_content.m_uFileHeaderSize = HEADER_SIZE;
782         m_file_content.m_uHashMaterialSize = HASH_SIZE;
783         m_file_content.m_uKeyMaterialSize = KEY_MAT_SIZE;
784
785         if (buffer[5] == 0) {
786                 SLOGI("[%s][%d] File dosn't containe encrypted key material!",
787                                 __FUNCTION__,
788                                 __LINE__);
789                 m_file_content.m_uEncryptedKeySize = 0;
790                 m_file_content.m_uFileContentSize = buf_size
791                 - (HEADER_SIZE + HASH_SIZE + KEY_MAT_SIZE);
792         } else if (buffer[5] == 1) {
793                 SLOGI("[%s][%d] File containes encrypted key material!",
794                                 __FUNCTION__,
795                                 __LINE__);
796                 m_file_content.m_uEncryptedKeySize = ENCRYPTED_KEY_SIZE;
797                 m_file_content.m_uFileContentSize = buf_size
798                 - (HEADER_SIZE + HASH_SIZE + KEY_MAT_SIZE + ENCRYPTED_KEY_SIZE);
799         }
800
801         SLOGI("[%s][%d] m_file_content.m_uFileContentSize = %i!",
802                         __FUNCTION__,
803                         __LINE__,
804                         m_file_content.m_uFileContentSize);
805         SLOGI("[%s][%d] m_file_content.m_uEncryptedKeySize = %i!",
806                         __FUNCTION__,
807                         __LINE__,
808                         m_file_content.m_uEncryptedKeySize);
809
810         switch (FileStructureType(ptr)) {
811                 case 0: {
812                         // [header][hash][data][key]
813                         m_file_content.m_pFileHeader = ptr;
814                         ptr += HEADER_SIZE;
815                         m_file_content.m_pHashMaterial = ptr;
816                         ptr += HASH_SIZE;
817                         m_file_content.m_pFileContent = ptr;
818                         ptr += m_file_content.m_uFileContentSize;
819                         m_file_content.m_pKeyMaterial = ptr;
820                         ptr += KEY_MAT_SIZE;
821                         break;
822                 }
823                 case 1: {
824                         // [header][hash][key][data]
825                         m_file_content.m_pFileHeader = ptr;
826                         ptr += HEADER_SIZE;
827                         m_file_content.m_pHashMaterial = ptr;
828                         ptr += HASH_SIZE;
829                         m_file_content.m_pKeyMaterial = ptr;
830                         ptr += KEY_MAT_SIZE;
831                         m_file_content.m_pFileContent = ptr;
832                         ptr += m_file_content.m_uFileContentSize;
833                         break;
834                 }
835                 case 2: {
836                         // [header][data][key][hash]
837                         m_file_content.m_pFileHeader = ptr;
838                         ptr += HEADER_SIZE;
839                         m_file_content.m_pFileContent = ptr;
840                         ptr += m_file_content.m_uFileContentSize;
841                         m_file_content.m_pKeyMaterial = ptr;
842                         ptr += KEY_MAT_SIZE;
843                         m_file_content.m_pHashMaterial = ptr;
844                         ptr += HASH_SIZE;
845                         break;
846                 }
847                 case 3: {
848                         // [header][key][data][hash]
849                         m_file_content.m_pFileHeader = ptr;
850                         ptr += HEADER_SIZE;
851                         m_file_content.m_pKeyMaterial = ptr;
852                         ptr += KEY_MAT_SIZE;
853                         m_file_content.m_pFileContent = ptr;
854                         ptr += m_file_content.m_uFileContentSize;
855                         m_file_content.m_pHashMaterial = ptr;
856                         ptr += HASH_SIZE;
857                         break;
858                 }
859                 case 4: {
860                         // [header][key][hash][data]
861                         m_file_content.m_pFileHeader = ptr;
862                         ptr += HEADER_SIZE;
863                         m_file_content.m_pKeyMaterial = ptr;
864                         ptr += KEY_MAT_SIZE;
865                         m_file_content.m_pHashMaterial = ptr;
866                         ptr += HASH_SIZE;
867                         m_file_content.m_pFileContent = ptr;
868                         ptr += m_file_content.m_uFileContentSize;
869                         break;
870                 }
871                 case 5: {
872                         // [header][data][hash][key]
873                         m_file_content.m_pFileHeader = ptr;
874                         ptr += HEADER_SIZE;
875                         m_file_content.m_pFileContent = ptr;
876                         ptr += m_file_content.m_uFileContentSize;
877                         m_file_content.m_pHashMaterial = ptr;
878                         ptr += HASH_SIZE;
879                         m_file_content.m_pKeyMaterial = ptr;
880                         ptr += KEY_MAT_SIZE;
881                         break;
882                 }
883                 default: {
884                         SLOGD("[%s][%d](SS_RET_FAIL) OUT OF THE FileStructureType : %d",
885                                         __FUNCTION__,
886                                         __LINE__,
887                                         FileStructureType(m_file_content.m_pFileHeader));
888                         return SS_RET_INVALID_FILE;
889                 }
890                 break;
891         }
892
893         // alloc meory for output content
894         m_file_content.m_pOutputContent =
895         new CBT_OCTET[m_file_content.m_uFileContentSize];
896         if (!m_file_content.m_pOutputContent) {
897                 SLOGD("[%s][%d](SS_RET_MALLOC_FAILED) CAN'T Malloc 'm_FileContent.m_pOutputContent' to attach it to SDC. ",
898                                 __FUNCTION__,
899                                 __LINE__);
900                 return SS_RET_MALLOC_FAILED;
901         }
902
903         // do we have encrypted key material attached
904         if (m_use_crypted_key) {
905                 SLOGI("[%s][%d] Using attached content key", __FUNCTION__, __LINE__);
906                 if (m_file_content.m_pFileHeader[5] != 1) {
907                         SLOGD("[%s][%d](SS_RET_FAIL) m_file_content.m_pFileHeader[5] != 1",
908                                         __FUNCTION__,
909                                         __LINE__);
910                         return SS_RET_FAIL;
911                 }
912
913                 m_file_content.m_pEncryptedKey = const_cast<CBT_OCTET*>(buffer + buf_size
914                                 - ENCRYPTED_KEY_SIZE);
915                 // revocer encrypted data size
916                 m_file_content.m_uEncryptedKeySize =
917                 (CBT_UINT32)m_file_content.m_pEncryptedKey[0]
918                 | (CBT_UINT32)m_file_content.m_pEncryptedKey[1] << 8
919                 | (CBT_UINT32)m_file_content.m_pEncryptedKey[2] << 16
920                 | (CBT_UINT32)m_file_content.m_pEncryptedKey[3] << 24;
921                 // it shall not be bigger then expected size
922                 if (m_file_content.m_uEncryptedKeySize > ENCRYPTED_KEY_SIZE) {
923                         SLOGF("[%s][%d] (SS_RET_INVALID_FILE) content key size is = %d",
924                                         __FUNCTION__,
925                                         __LINE__,
926                                         m_file_content.m_uEncryptedKeySize);
927                         return SS_RET_INVALID_FILE;
928                 }
929
930                 SLOGI("[%s][%d] Content key size is = %d",
931                                 __FUNCTION__,
932                                 __LINE__,
933                                 m_file_content.m_uEncryptedKeySize);
934
935                 SLOGI("[%s][%d] Decrypting content key", __FUNCTION__, __LINE__);
936         }
937
938         return SS_RET_SUCCESS;
939 #endif
940 }
941
942 int secure_file::serialize_data(unsigned char** buffer,
943     unsigned int& ret_size) {
944 #ifdef _SECOS_SIM_
945         *buffer = (unsigned char*)OsaMalloc(m_write_data_size);
946     if (NULL == *buffer) {
947                 //SLOGE("fail to alloc memory for data.");
948                 return SS_RET_MALLOC_FAILED;
949         }
950
951         memcpy(*buffer, m_write_data, m_write_data_size);
952         ret_size = m_write_data_size;
953         return SS_RET_SUCCESS;
954 #else
955
956         unsigned char* data = NULL;
957         *buffer = NULL;
958         ret_size = 0;
959
960         int buf_size = m_file_content.m_uFileHeaderSize;
961         buf_size += m_file_content.m_uKeyMaterialSize;
962         buf_size += m_file_content.m_uFileContentSize;
963         buf_size += m_file_content.m_uHashMaterialSize;
964
965         if (m_file_content.m_pFileHeader[5] == 1) {
966                 buf_size += ENCRYPTED_KEY_SIZE;
967         }
968
969         data = (unsigned char*)OsaMalloc(buf_size + 1);
970         if (NULL == data) {
971                 SLOGE("fail to alloc memory for data.");
972                 return SS_RET_MALLOC_FAILED;
973         }
974
975         unsigned char* ptr = data;
976         switch (FileStructureType(m_file_content.m_pFileHeader)) {
977                 case 0: {
978                         // [header][hash][data][key]
979                         memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
980                         ptr += HEADER_SIZE;
981                         memcpy(ptr, m_file_content.m_pHashMaterial, HASH_SIZE);
982                         ptr += HASH_SIZE;
983                         memcpy(ptr,
984                                         m_file_content.m_pFileContent,
985                                         m_file_content.m_uFileContentSize);
986                         ptr += m_file_content.m_uFileContentSize;
987                         memcpy(ptr, m_file_content.m_pKeyMaterial, KEY_MAT_SIZE);
988                         ptr += KEY_MAT_SIZE;
989                         break;
990                 }
991                 case 1: {
992                         // [header][hash][key][data]
993                         memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
994                         ptr += HEADER_SIZE;
995                         memcpy(ptr, m_file_content.m_pHashMaterial, HASH_SIZE);
996                         ptr += HASH_SIZE;
997                         memcpy(ptr, m_file_content.m_pKeyMaterial, KEY_MAT_SIZE);
998                         ptr += KEY_MAT_SIZE;
999                         memcpy(ptr,
1000                                         m_file_content.m_pFileContent,
1001                                         m_file_content.m_uFileContentSize);
1002                         ptr += m_file_content.m_uFileContentSize;
1003                         break;
1004                 }
1005                 case 2: {
1006                         // [header][data][key][hash]
1007                         memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
1008                         ptr += HEADER_SIZE;
1009                         memcpy(ptr,
1010                                         m_file_content.m_pFileContent,
1011                                         m_file_content.m_uFileContentSize);
1012                         ptr += m_file_content.m_uFileContentSize;
1013                         memcpy(ptr, m_file_content.m_pKeyMaterial, KEY_MAT_SIZE);
1014                         ptr += KEY_MAT_SIZE;
1015                         memcpy(ptr, m_file_content.m_pHashMaterial, HASH_SIZE);
1016                         ptr += HASH_SIZE;
1017                         break;
1018                 }
1019                 case 3: {
1020                         // [header][key][data][hash]
1021                         memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
1022                         ptr += HEADER_SIZE;
1023                         memcpy(ptr, m_file_content.m_pKeyMaterial, KEY_MAT_SIZE);
1024                         ptr += KEY_MAT_SIZE;
1025                         memcpy(ptr,
1026                                         m_file_content.m_pFileContent,
1027                                         m_file_content.m_uFileContentSize);
1028                         ptr += m_file_content.m_uFileContentSize;
1029                         memcpy(ptr, m_file_content.m_pHashMaterial, HASH_SIZE);
1030                         ptr += HASH_SIZE;
1031                         break;
1032                 }
1033                 case 4: {
1034                         // [header][key][hash][data]
1035                         memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
1036                         ptr += HEADER_SIZE;
1037                         memcpy(ptr, m_file_content.m_pKeyMaterial, KEY_MAT_SIZE);
1038                         ptr += KEY_MAT_SIZE;
1039                         memcpy(ptr, m_file_content.m_pHashMaterial, HASH_SIZE);
1040                         ptr += HASH_SIZE;
1041                         memcpy(ptr,
1042                                         m_file_content.m_pFileContent,
1043                                         m_file_content.m_uFileContentSize);
1044                         ptr += m_file_content.m_uFileContentSize;
1045                         break;
1046                 }
1047                 case 5: {
1048                         // [header][data][hash][key]
1049                         memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
1050                         ptr += HEADER_SIZE;
1051                         memcpy(ptr,
1052                                         m_file_content.m_pFileContent,
1053                                         m_file_content.m_uFileContentSize);
1054                         ptr += m_file_content.m_uFileContentSize;
1055                         memcpy(ptr, m_file_content.m_pHashMaterial, HASH_SIZE);
1056                         ptr += HASH_SIZE;
1057                         memcpy(ptr, m_file_content.m_pKeyMaterial, KEY_MAT_SIZE);
1058                         ptr += KEY_MAT_SIZE;
1059                         break;
1060                 }
1061                 default: {
1062                         SLOGD("[%s][%d](SS_RET_FAIL) OUT OF THE FileStructureType : %d",
1063                                         __FUNCTION__,
1064                                         __LINE__,
1065                                         FileStructureType(m_file_content.m_pFileHeader));
1066                         OsaFree(data);
1067                         return SS_RET_FAIL;
1068                 }
1069                 break;
1070         }
1071
1072         if (m_file_content.m_pFileHeader[5] == 1) {
1073                 SLOGI("[%s][%d] Writing encrypted key", __FUNCTION__, __LINE__);
1074                 memcpy(ptr, m_file_content.m_EncryptedKeyBuffer, ENCRYPTED_KEY_SIZE);
1075         }
1076
1077         *buffer = data;
1078         ret_size = buf_size;
1079
1080         return SS_RET_SUCCESS;
1081 #endif
1082 }
1083
1084 int secure_file::write_temp_store(unsigned char* data, unsigned int size) {
1085         if (-1 == m_cache->write(m_full_path, data, size)) {
1086                 SLOGI("[%s][%d] Writing to cache storage failed.", __FUNCTION__, __LINE__);
1087                 OsaFree(data);
1088                 return SS_RET_FAIL;
1089         }
1090
1091         OsaFree(data);
1092         return SS_RET_SUCCESS;
1093 }
1094
1095 int secure_file::write_persistent_store(unsigned char* data,
1096     unsigned int size) {
1097 #ifdef _SECOS_SIM_
1098         char filename[MAX_FILENAME_LEN] = {0};
1099         get_data_name(filename, false);
1100         int iRet = file_op::write_file(filename, data, size);
1101         OsaFree(data);
1102         return iRet;
1103 #else
1104         shm_manager shm_mgr;
1105         if (-1 == shm_mgr.init())
1106         {
1107                 SLOGE("Failed to init shm manager.");
1108                 return SS_RET_COMM_ERR;
1109         }
1110
1111         swdss_request req;
1112         req.type = REQ_WRITE;
1113         memcpy(req.data_name, m_full_path, SS_FULL_DATA_NAME_LEN);
1114         req.data = data;
1115         req.data_size = size;
1116
1117         SLOGE("Data size = %d.", size);
1118
1119         shm_mgr.lock();
1120         shm_mgr.put_request(&req);
1121         OsaFree(data);
1122
1123         if (-1 == call_ta_service())
1124         {
1125                 SLOGE("Failed to call ta service.");
1126                 return SS_RET_COMM_ERR;
1127         }
1128
1129         swdss_response rsp;
1130         shm_mgr.get_response(&rsp);
1131
1132         return rsp.retcode;
1133 #endif
1134 }
1135
1136 int secure_file::read_temp_store(unsigned char** buffer,
1137     unsigned int& ret_size) {
1138         if (0 != m_cache->read(m_full_path, buffer, ret_size)) {
1139                 return SS_RET_CANT_FIND_REQUESTED_DATA;
1140         }
1141
1142         return SS_RET_SUCCESS;
1143 }
1144
1145 int secure_file::read_persistent_store(unsigned char** buffer,
1146     unsigned int& ret_size) {
1147 #ifdef _SECOS_SIM_
1148         char filename[MAX_FILENAME_LEN] = {0};
1149         get_data_name(filename, false);
1150         return file_op::read_file(filename, buffer, ret_size);
1151 #else
1152
1153         shm_manager shm_mgr;
1154         if (-1 == shm_mgr.init())
1155         {
1156                 SLOGE("Failed to init shm manager.");
1157                 return SS_RET_COMM_ERR;
1158         }
1159
1160         swdss_request req;
1161         req.type = REQ_READ;
1162         memcpy(req.data_name, m_full_path, SS_FULL_DATA_NAME_LEN);
1163         req.data = NULL;
1164         req.data_size = 0;
1165
1166         shm_mgr.lock();
1167         shm_mgr.put_request(&req);
1168
1169         if (-1 == call_ta_service())
1170         {
1171                 SLOGE("Failed to call ta service.");
1172                 return SS_RET_COMM_ERR;
1173         }
1174
1175         swdss_response rsp;
1176         shm_mgr.get_response(&rsp);
1177
1178         if (SS_RET_SUCCESS != rsp.retcode)
1179         {
1180                 return rsp.retcode;
1181         }
1182
1183         *buffer = rsp.data;
1184         ret_size = rsp.data_size;
1185
1186         SLOGI("ret_size = %d", ret_size);
1187
1188         return SS_RET_SUCCESS;
1189
1190 #endif
1191 }
1192
1193 int secure_file::remove_persistent_store(bool is_dir) {
1194 #ifdef _SECOS_SIM_
1195         char filename[MAX_FILENAME_LEN] = {0};
1196         get_data_name(filename, is_dir);
1197         int iret = SS_RET_SUCCESS;
1198         if (is_dir) {
1199                 iret = file_op::remove_folder(filename);
1200         } else {
1201                 iret = file_op::remove_file(filename);
1202         }
1203
1204         return iret;
1205
1206 #else
1207
1208         shm_manager shm_mgr;
1209         if (-1 == shm_mgr.init())
1210         {
1211                 SLOGE("Failed to init shm manager.");
1212                 return SS_RET_COMM_ERR;
1213         }
1214
1215         swdss_request req;
1216         req.type = is_dir ? REQ_BATCH_REMOVE: REQ_REMOVE;
1217         memcpy(req.data_name, m_full_path, SS_FULL_DATA_NAME_LEN);
1218         req.data = NULL;
1219         req.data_size = 0;
1220
1221         shm_mgr.lock();
1222         shm_mgr.put_request(&req);
1223
1224         if (-1 == call_ta_service())
1225         {
1226                 SLOGE("Failed to call ta service.");
1227                 return SS_RET_COMM_ERR;
1228         }
1229
1230         swdss_response rsp;
1231         shm_mgr.get_response(&rsp);
1232
1233         return rsp.retcode;
1234 #endif
1235 }
1236
1237 int secure_file::check_file_content() {
1238 #ifdef _SECOS_SIM_
1239         return 0;
1240 #else
1241
1242         // compute file hash
1243         CBT_OCTET computed_hash[CCryptoEngine::Hash_Size];
1244         compute_file_hash(computed_hash);
1245
1246         CBT_OCTET* stored_hash;
1247         stored_hash = m_file_content.m_pHashMaterial;
1248
1249         if (memcmp(computed_hash, stored_hash, CCryptoEngine::Hash_Size)) {
1250                 SLOGD("[%s][%d](SS_RET_INVALID_FILE) Hash is DIFFERENT!!!",
1251                                 __FUNCTION__,
1252                                 __LINE__);
1253                 return SS_RET_INVALID_FILE;
1254         }
1255
1256         return SS_RET_SUCCESS;
1257 #endif
1258 }
1259
1260 int secure_file::decrypt_data() {
1261 #ifdef _SECOS_SIM_
1262         m_file_content.m_pOutputContentSize = m_read_data_size;
1263         m_file_content.m_pOutputContent = m_read_data;
1264         m_read_data = NULL;
1265         return 0;
1266 #else
1267
1268         if (m_use_crypted_key) {
1269                 int ret;
1270                 unsigned long uDecryptedKeySize;
1271                 SLOGI("[%s][%d] Decrypting content key", __FUNCTION__, __LINE__);
1272
1273                 ret = CCryptoEngine::RSADecrypt(m_file_content.m_EncryptedKeyBuffer,
1274                                 &uDecryptedKeySize,
1275                                 m_file_content.m_pEncryptedKey + 4,
1276                                 m_file_content.m_uEncryptedKeySize,
1277                                 m_rsa_key.rsa_n_data,
1278                                 m_rsa_key.rsa_n_len,
1279                                 m_rsa_key.rsa_d_data,
1280                                 m_rsa_key.rsa_d_len);
1281
1282                 if (CRYPTO_SUCCESS != ret) {
1283                         SLOGF("[%s][%d](SS_RET_FAIL) RSADecrypt failed!", __FUNCTION__, __LINE__);
1284                         return SS_RET_FAIL;
1285                 }
1286
1287                 // content key size shall be exactly as expected
1288                 if (uDecryptedKeySize != (unsigned long)(CCryptoEngine::Key_Size)) {
1289                         SLOGF("[%s][%d](SS_RET_INVALID_FILE) Contexct key size is wrong %lu",
1290                                         __FUNCTION__,
1291                                         __LINE__,
1292                                         uDecryptedKeySize);
1293                         return SS_RET_INVALID_FILE;
1294                 }
1295
1296                 m_file_content.m_pOutputContentSize =
1297                 DecryptEx(m_file_content.m_pOutputContent,
1298                                 m_file_content.m_pFileContent,
1299                                 m_file_content.m_uFileContentSize,
1300                                 m_file_content.m_EncryptedKeyBuffer);
1301
1302                 if (0 == m_file_content.m_pOutputContentSize) {
1303                         SLOGD("[%s][%d](ERROR) TZ Can't DEcrypt data WITH EncryptedKey mode (0 == m_file_content.m_pOutputContentSize)",
1304                                         __FUNCTION__,
1305                                         __LINE__);
1306                         SLOGF("[%s][%d](ERROR)", __FUNCTION__, __LINE__);
1307                         return SS_RET_INTERNAL_ERROR;
1308                 }
1309         } else {
1310                 m_file_content.m_pOutputContentSize =
1311                 Decrypt(m_file_content.m_pOutputContent,
1312                                 m_file_content.m_pFileContent,
1313                                 m_file_content.m_uFileContentSize,
1314                                 m_file_content.m_pKeyMaterial,
1315                                 m_options);
1316
1317                 if (0 == m_file_content.m_pOutputContentSize) {
1318                         SLOGD("[%s][%d](ERROR) TZ Can't DEcrypt data WITHOUT EncryptedKey mode (0 == m_file_content.m_pOutputContentSize)",
1319                                         __FUNCTION__,
1320                                         __LINE__);
1321                         SLOGF("[%s][%d](ERROR)", __FUNCTION__, __LINE__);
1322                         return SS_RET_INTERNAL_ERROR;
1323                 }
1324         }
1325
1326         return SS_RET_SUCCESS;
1327 #endif
1328 }
1329
1330 secure_file::~secure_file() {
1331         (void)finalize();
1332 }
1333
1334 int secure_file::prepare_data(unsigned char** ret_buf, unsigned int * ret_size,
1335     unsigned char* buffer, unsigned int buf_size, unsigned int offset) {
1336         // if partial rw is not enabled.
1337         if (!(m_options & SS_OPT_PARTIAL_RW)) {
1338                 *ret_buf = buffer;
1339                 *ret_size = buf_size;
1340                 return SS_RET_SUCCESS;
1341         }
1342
1343         //partial write, read data first
1344         m_is_partial_write = true;
1345         unsigned char* data = NULL;
1346         unsigned char* orig_data = NULL;
1347         unsigned int ori_size = 0xffff;
1348
1349         bool tmp_flag = m_use_crypted_key;
1350         m_use_crypted_key = false;
1351         int iRet = read(&orig_data, &ori_size, 0);
1352         m_use_crypted_key = tmp_flag;
1353
1354         if (SS_RET_SUCCESS != iRet) {
1355                 // data not exist and offset=0, new data entry is created.
1356                 if ((SS_RET_CANT_FIND_REQUESTED_DATA == iRet) && (0 == offset)) {
1357                         *ret_buf = buffer;
1358                         *ret_size = buf_size;
1359                         m_is_partial_write = false;
1360                         return SS_RET_SUCCESS;
1361                 }
1362
1363                 SLOGF("[%s][%d]Read data for partial write failed.", __FUNCTION__,
1364                     __LINE__);
1365                 return iRet;
1366         }
1367
1368         if (offset > ori_size) {
1369                 SLOGF("[%s][%d]offset(%d) exceed data size(%d).", __FUNCTION__, __LINE__,
1370                     offset, ori_size);
1371                 OsaFree(orig_data);
1372                 return SS_RET_OFFSET_ERR;
1373         }
1374
1375         unsigned int add_size =
1376             (offset + buf_size) > ori_size ? (offset + buf_size - ori_size) : 0;
1377         data = (unsigned char*)OsaMalloc(ori_size + add_size);
1378         if (NULL == data) {
1379                 SLOGF("[%s][%d]Failed to alloc memory for data.", __FUNCTION__, __LINE__);
1380                 OsaFree(orig_data);
1381                 return SS_RET_MALLOC_FAILED;
1382         }
1383
1384         unsigned char* dest = data;
1385         memcpy(dest, orig_data, offset);
1386         dest += offset;
1387         memcpy(dest, buffer, buf_size);
1388         dest += buf_size;
1389
1390         if (0 == add_size) {
1391                 memcpy(dest, orig_data + offset + buf_size, ori_size - offset - buf_size);
1392         }
1393
1394         *ret_buf = data;
1395         *ret_size = ori_size + add_size;
1396         OsaFree(orig_data);
1397
1398         return SS_RET_SUCCESS;
1399 }
1400
1401 int secure_file::write(unsigned char* buffer, unsigned int buf_size,
1402     unsigned int offset) {
1403         SLOGE("Entering secure_file::write, buf_size = %d.", buf_size);
1404
1405         if ((NULL == buffer) || ('\0' == m_data_name[0]) || (0 == buf_size)) {
1406                 SLOGE("[%s] input param error.\n", __FUNCTION__);
1407                 return SS_RET_INVALID_PARAM;
1408         }
1409
1410         if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
1411                 return SS_RET_INVALID_DATA_NAME;
1412         }
1413
1414         if (SS_MAX_DATA_SIZE < buf_size) {
1415                 return SS_RET_DATA_SIZE_IS_TOO_BIG;
1416         }
1417
1418         memset(&m_file_content, 0, sizeof(m_file_content));
1419
1420         int iRet = prepare_data(&m_write_data, &m_write_data_size, buffer, buf_size,
1421             offset);
1422         if (SS_RET_SUCCESS != iRet) {
1423                 SLOGF("[%s][%d]Failed to prepare data.", __FUNCTION__, __LINE__);
1424                 return iRet;
1425         }
1426
1427         SLOGE(" prepare_data data size = %d.", m_write_data_size);
1428
1429         if (SS_MAX_DATA_SIZE < m_write_data_size) {
1430                 SLOGF("[%s][%d]Data size %d is too big.", __FUNCTION__, __LINE__,
1431                     m_write_data_size);
1432                 return SS_RET_DATA_SIZE_IS_TOO_BIG;
1433         }
1434
1435         // generating new key material
1436         int ret = 0;
1437
1438         // preparing file content for writing
1439         ret = prepare_file_content(m_write_data, m_write_data_size);
1440         if (ret) {
1441                 return ret;
1442         }
1443
1444         // drive path
1445         derive_file_path();
1446
1447         // serialize data
1448         unsigned char* data = NULL;
1449         unsigned int size = 0;
1450         if (SS_RET_SUCCESS != (ret = serialize_data(&data, size))) {
1451                 free(data);
1452                 return ret;
1453         }
1454
1455         // write to cache
1456         if (m_options & SS_OPT_TEMPORARY) {
1457                 return write_temp_store(data, size);
1458         }
1459
1460         // writing data into file
1461         ret = write_persistent_store(data, size);
1462
1463         return ret;
1464 }
1465
1466 int secure_file::read(unsigned char** ret_buf, unsigned int* read_size,
1467     unsigned int offset) {
1468         SLOGI("Entering secure_file::read");
1469
1470         if (('\0' == m_data_name[0]) || (NULL == read_size)) {
1471                 return SS_RET_INVALID_PARAM;
1472         }
1473
1474         if ((m_options & SS_OPT_PARTIAL_RW) && (0 == *read_size)) {
1475                 SLOGE("Read zero byte data.");
1476                 return SS_RET_INVALID_PARAM;
1477         }
1478
1479         if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
1480                 return SS_RET_INVALID_DATA_NAME;
1481         }
1482
1483         int ret = 0;
1484
1485         unsigned int required_size = *read_size;
1486         unsigned int off_set = offset;
1487         *read_size = 0;
1488
1489         // cleaning internal file structure representation
1490         memset(&m_file_content, 0, sizeof(m_file_content));
1491
1492         derive_file_path();
1493
1494         // read from cache storage
1495         if (m_options & SS_OPT_TEMPORARY) {
1496                 if (SS_RET_SUCCESS
1497                     != (ret = read_temp_store(&m_read_data, m_read_data_size))) {
1498                         SLOGE("[%s][%d](ERROR) Read data from temp store failed.", __FUNCTION__,
1499                             __LINE__);
1500                         return ret;
1501                 }
1502         } else {
1503                 ret = read_persistent_store(&m_read_data, m_read_data_size);
1504                 if (ret) {
1505                         return ret;
1506                 }
1507         }
1508
1509         // Parsing content
1510         ret = parse_file_content(m_read_data, m_read_data_size);
1511         if (ret) {
1512                 return ret;
1513         }
1514
1515         // checking content integrity
1516         ret = check_file_content();
1517         if (ret) {
1518                 return ret;
1519         }
1520
1521         // decrypting data
1522         ret = decrypt_data();
1523         if (ret) {
1524                 SLOGE("[%s][%d](ERROR) DecryptData() // iRet : %d", __FUNCTION__, __LINE__,
1525                     ret);
1526                 return ret;
1527         }
1528
1529         // partial rw not enabled.
1530         if (!(m_options & SS_OPT_PARTIAL_RW)) {
1531                 off_set = 0;
1532                 required_size = m_file_content.m_pOutputContentSize + 1;
1533         }
1534
1535         // partial read supported
1536         if (off_set >= m_file_content.m_pOutputContentSize - 1) {
1537                 SLOGE("[%s][%d]offset(%d) exceed data size(%d).", __FUNCTION__, __LINE__,
1538                     off_set, m_file_content.m_pOutputContentSize);
1539                 return SS_RET_OFFSET_ERR;
1540         }
1541
1542         // copy data
1543         unsigned ret_size =
1544             m_file_content.m_pOutputContentSize >= (off_set + required_size) ?
1545                 required_size : (m_file_content.m_pOutputContentSize - off_set);
1546
1547         *ret_buf = (unsigned char*)OsaMalloc(ret_size);
1548         if (*ret_buf == NULL) {
1549                 SLOGE("[%s][%d]Failed to alloc memory.", __FUNCTION__, __LINE__);
1550                 return SS_RET_MALLOC_FAILED;
1551         }
1552
1553         memcpy(*ret_buf, m_file_content.m_pOutputContent + off_set, ret_size);
1554         *read_size = ret_size;
1555
1556         return SS_RET_SUCCESS;
1557 }
1558
1559 int secure_file::write_ex(unsigned char* buffer, unsigned int buf_size,
1560     unsigned int offset, const unsigned char* rsa_n_data,
1561     unsigned long rsa_n_len, const unsigned char* rsa_e_data,
1562     unsigned long rsa_e_len) {
1563         int ret = 0;
1564
1565         if ((NULL == buffer) || ('\0' == m_data_name[0]) || (0 == buf_size)) {
1566                 SLOGE("[%s] input param error.\n", __FUNCTION__);
1567                 return SS_RET_INVALID_PARAM;
1568         }
1569
1570         if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
1571                 return SS_RET_INVALID_DATA_NAME;
1572         }
1573
1574         if (SS_MAX_DATA_SIZE < buf_size) {
1575                 return SS_RET_DATA_SIZE_IS_TOO_BIG;
1576         }
1577
1578         // checking input correctness
1579         if ((NULL == rsa_n_data) || (NULL == rsa_e_data) || (rsa_n_len > RSA_KEY_SIZE)
1580             || (rsa_e_len > RSA_KEY_SIZE) || (rsa_e_len > rsa_n_len)) {
1581                 return SS_RET_INVALID_RSA_PARAM;
1582         }
1583
1584         // initiating special mode
1585         m_use_crypted_key = true;
1586
1587         // initializing RSA key data
1588         m_rsa_key.rsa_e_data = const_cast<uint8_t*>(rsa_e_data);
1589         m_rsa_key.rsa_e_len = rsa_e_len;
1590         m_rsa_key.rsa_n_data = const_cast<uint8_t*>(rsa_n_data);
1591         m_rsa_key.rsa_n_len = rsa_n_len;
1592         m_rsa_key.rsa_d_data = NULL;
1593         m_rsa_key.rsa_d_len = 0;
1594
1595         // writing data into file
1596         ret = write(buffer, buf_size, offset);
1597
1598         // removing special mode
1599         m_use_crypted_key = false;
1600
1601         return ret;
1602 }
1603
1604 int secure_file::read_ex(unsigned char** ret_buf, unsigned int* read_size,
1605     unsigned int offset, const unsigned char* rsa_n_data,
1606     unsigned long rsa_n_len, const unsigned char* rsa_d_data,
1607     unsigned long rsa_d_len) {
1608         if (('\0' == m_data_name[0]) || (NULL == read_size)) {
1609                 return SS_RET_INVALID_PARAM;
1610         }
1611
1612         if ((m_options & SS_OPT_PARTIAL_RW) && (0 == *read_size)) {
1613                 SLOGE("Read zero byte data.");
1614                 return SS_RET_INVALID_PARAM;
1615         }
1616
1617         if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
1618                 return SS_RET_INVALID_DATA_NAME;
1619         }
1620
1621         int ret = 0;
1622
1623         // initiating special mode
1624         m_use_crypted_key = true;
1625
1626         // checking input correctness
1627         if ((NULL == rsa_n_data) || (NULL == rsa_d_data) || (rsa_n_len > RSA_KEY_SIZE)
1628             || (rsa_d_len > RSA_KEY_SIZE) || (rsa_d_len > rsa_n_len)) {
1629                 return SS_RET_INVALID_RSA_PARAM;
1630         }
1631
1632         // initializing RSA key data
1633         m_rsa_key.rsa_d_data = const_cast<uint8_t*>(rsa_d_data);
1634         m_rsa_key.rsa_d_len = rsa_d_len;
1635         m_rsa_key.rsa_n_data = const_cast<uint8_t*>(rsa_n_data);
1636         m_rsa_key.rsa_n_len = rsa_n_len;
1637         m_rsa_key.rsa_e_data = NULL;
1638         m_rsa_key.rsa_e_len = 0;
1639
1640         // writing data into file
1641         ret = read(ret_buf, read_size, offset);
1642
1643         // removing special mode
1644         m_use_crypted_key = false;
1645
1646         return ret;
1647 }
1648
1649 int secure_file::validate() {
1650         if ('\0' == m_data_name[0]) {
1651                 return SS_RET_INVALID_PARAM;
1652         }
1653
1654         if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
1655                 return SS_RET_INVALID_DATA_NAME;
1656         }
1657
1658         int ret = 0;
1659
1660         // cleaning internal file structure representation
1661         memset(&m_file_content, 0, sizeof(m_file_content));
1662
1663         // drive path
1664         derive_file_path();
1665
1666         // read from cache storage
1667         if (m_options & SS_OPT_TEMPORARY) {
1668                 if (SS_RET_SUCCESS
1669                     != (ret = read_temp_store(&m_read_data, m_read_data_size))) {
1670                         SLOGD("[%s][%d](ERROR) Read data from temp store failed.", __FUNCTION__,
1671                             __LINE__);
1672                         return ret;
1673                 }
1674         } else {
1675                 ret = read_persistent_store(&m_read_data, m_read_data_size);
1676                 if (ret) {
1677                         return ret;
1678                 }
1679         }
1680
1681         // Parsing content
1682         ret = parse_file_content(m_read_data, m_read_data_size);
1683         if (ret) {
1684                 return ret;
1685         }
1686
1687         // checking content integrity
1688         return check_file_content();
1689 }
1690
1691 int secure_file::remove() {
1692         if ('\0' == m_data_name[0]) {
1693                 return SS_RET_INVALID_PARAM;
1694         }
1695
1696         if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
1697                 return SS_RET_INVALID_DATA_NAME;
1698         }
1699
1700         derive_file_path();
1701
1702         if (SS_OPT_TEMPORARY & m_options) {
1703                 if (SS_RET_SUCCESS != m_cache->remove(m_full_path)) {
1704                         SLOGE("Data file not exist, path = [%s].", m_full_path);
1705                         return SS_RET_CANT_FIND_REQUESTED_DATA;
1706                 }
1707
1708                 return SS_RET_SUCCESS;
1709         }
1710
1711         return remove_persistent_store(false);
1712 }
1713
1714 int secure_file::clear_storage() {
1715         derive_file_path();
1716
1717         if (SS_OPT_TEMPORARY & m_options) {
1718                 return m_cache->batch_remove(m_full_path);
1719         }
1720
1721         return remove_persistent_store(true);
1722 }
1723
1724 #ifdef _SECOS_SIM_
1725 #define SS_CRED_LEN 36
1726 void secure_file::get_data_name(char* data_name, bool is_dir) {
1727         char* ptr = data_name;
1728         strncpy(ptr, SWD_SS_ROOT, MAX_FILENAME_LEN - (ptr-data_name));
1729         ptr += strlen(SWD_SS_ROOT);
1730
1731         // first 4 bytes for directory.
1732         //byte_to_hex(ptr, (uint8_t*)m_full_path, 4);
1733         strncpy(ptr, m_full_path, SS_CRED_LEN);
1734         ptr[SS_CRED_LEN] = '\0';
1735
1736         if (is_dir) {
1737                 return;
1738         }
1739
1740         // next 8 bytes for filename
1741         strncpy(ptr, m_full_path, MAX_FILENAME_LEN - (ptr-data_name));
1742         data_name[MAX_FILENAME_LEN - 1] = '\0';
1743         //memset(ptr, '/', 1);
1744         //ptr += 1;
1745         //memcpy(ptr,m_full_path+SS_CRED_LEN,)
1746         //byte_to_hex(ptr, (uint8_t*)&m_full_path[4], 8);
1747 }
1748 #endif
1749