2 * Copyright (c) 2013-2017 Samsung Electronics Co., Ltd All Rights Reserved
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 #include "ss_crypto.h"
19 #include "secure_file.h"
22 #include "OsaLinuxUser.h"
27 //#define SWD_SS_ROOT "/opt/usr/apps/tz_simulator/data/swdss/"
28 #define SWD_SS_ROOT "/tmp/tastore2/"
32 #define MAX_FILENAME_LEN 256
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;
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};
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};
55 const unsigned char g_Prekey[] = {0xa1, 0x21, 0x51, 0x71, 0xf1, 0x01, 0xd1,
56 0x31, 0x41, 0x01, 0x01, 0x91, 0x91, 0xb1, 0xe1, 0x11};
58 // PBKDF2 iterations count
59 static const CBT_UINT32 PHASE1_ITER = 200;
60 static const CBT_UINT32 PHASE2_ITER = 250;
64 * \brief Determine file structure index
65 * \param pFileHeader [in] pointer to file header
66 * \return Structure index
68 static CBT_UINT32 FileStructureType(CBT_OCTET* pFileHeader) {
69 return (pFileHeader[6] ^ pFileHeader[7]) % 6;
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) {
77 CBT_OCTET pU[32] = {0};
78 CBT_OCTET pT[32] = {0};
81 memcpy(pU, pSalt, SALT_SIZE);
83 // preparing crypto conteiner for HMAC-SHA1
84 CryptoCoreContainer *crt = create_CryptoCoreContainer(alg);
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);
93 destroy_CryptoCoreContainer(crt);
95 memcpy(pKey, pT, CCryptoEngine::Key_Size);
100 static int MDeriveCommonKey1(const CBT_OCTET* pKeyMaterial,
101 CBT_UINT32 uKeyMaterialSize, CBT_OCTET* pKey) {
103 PBKDF2(pKeyMaterial, uKeyMaterialSize, CSALT1, PHASE1_ITER, pKey, ID_HSHA1);
108 static int MDeriveCommonKey2(const CBT_OCTET* pKeyMaterial,
109 CBT_UINT32 uKeyMaterialSize, CBT_OCTET* pKey) {
111 PBKDF2(pKeyMaterial, uKeyMaterialSize, CSALT2, PHASE2_ITER, pKey, ID_HSHA1);
116 static int MDeriveUniqueKey1(const CBT_OCTET* pKeyMaterial,
117 CBT_UINT32 uKeyMaterialSize, CBT_OCTET* pKey) {
119 PBKDF2(pKeyMaterial, uKeyMaterialSize, USALT1, PHASE1_ITER, pKey, ID_HSHA1);
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, };
130 if (uKeyMaterialSize > KEY_MAT_SIZE) {
131 SLOGE("uKeyMaterialSize %d is too big.\n", uKeyMaterialSize);
132 return SS_RET_INTERNAL_ERROR;
135 pBuffer = new(std::nothrow) CBT_OCTET[uKeyMaterialSize + 16];
137 SLOGE("Alloc memory failed.\n");
138 return SS_RET_MALLOC_FAILED;
141 memset(pBuffer, 0, uKeyMaterialSize + 16);
143 #if defined(_SECOS_SIM_)
144 #define UCI_HW_SECRET_KEY 0
145 #define ID_UCI_ENC_ECB 0
148 int iRet = CCryptoEngine::HWEncrypt(pBuffer, &nSize, (CBT_OCTET*)pKeyMaterial,
149 uKeyMaterialSize, key,
153 SLOGE("Failed to do HWEncrypt, ret_code %d.\n", iRet);
155 return SS_RET_INTERNAL_ERROR;
158 memset(pBuffer + CCryptoEngine::Key_Size, 0, 16); //hack
161 PBKDF2(pBuffer, nSize, USALT2, PHASE2_ITER, pKey, ID_HSHA1);
168 static int GenKey(const CBT_OCTET* pKeyMaterial, CBT_OCTET* pKey,
169 CBT_UINT32 options) {
171 CBT_OCTET pBufKey[CCryptoEngine::Key_Size];
173 // performing first transformation
174 if (options & SS_OPT_COMMON) {
175 iRet = MDeriveCommonKey1(pKeyMaterial, KEY_MAT_SIZE, pBufKey);
177 iRet = MDeriveUniqueKey1(pKeyMaterial, KEY_MAT_SIZE, pBufKey);
181 SLOGE("Failed to derive key 1st phase.\n");
182 return SS_RET_INTERNAL_ERROR;
185 // performing second transformation
186 if (options & SS_OPT_COMMON) {
187 iRet = MDeriveCommonKey2(pBufKey, CCryptoEngine::Key_Size, pKey);
189 iRet = MDeriveUniqueKey2(pBufKey, CCryptoEngine::Key_Size, pKey);
193 SLOGE("Failed to derive key 2nd phase.\n");
194 return SS_RET_INTERNAL_ERROR;
200 int Encrypt(uint8_t* dest, uint8_t* src, unsigned long data_len,
201 uint8_t* key_material, uint32_t options) {
203 CBT_OCTET pKey[CCryptoEngine::Key_Size];
205 // generating random key data
206 CCryptoEngine::Random(key_material, KEY_MAT_SIZE);
208 iRet = GenKey(key_material, pKey, options);
210 SLOGE("Failed to do MGenKey.\n");
214 return CCryptoEngine::Encrypt(dest, src, data_len, pKey, 0);
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];
224 // generating random key data
225 CCryptoEngine::Random(key_material, KEY_MAT_SIZE);
227 iRet = GenKey(key_material, pKey, options);
229 SLOGE("Failed to do MGenKey.\n");
233 unsigned int cipherTextLen, t;
234 CryptoCoreContainer *crt = create_CryptoCoreContainer(ID_AES);
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));
246 destroy_CryptoCoreContainer(crt);
248 ret = CCryptoEngine::Encrypt(dest, src, data_len, pKey, 0);
253 int Decrypt(uint8_t* dest, uint8_t* src, unsigned long data_len,
254 const uint8_t* key_material, uint32_t options) {
256 CBT_OCTET pKey[CCryptoEngine::Key_Size];
258 if (key_material == 0) {
259 SLOGE("Key material is NULL.\n");
263 iRet = GenKey(key_material, pKey, options);
265 SLOGE("Failed to do MGenKey.\n");
269 return CCryptoEngine::Decrypt(dest, src, data_len, pKey, 0);
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*/) {
276 //unsigned long uDecryptedKeySize;
277 uint8_t decryptedKeyBuffer[ENCRYPTED_KEY_SIZE];
279 unsigned int plainTextLen, t;
280 CryptoCoreContainer *crt = create_CryptoCoreContainer(ID_AES);
285 crt->SE_init(crt, ID_DEC_ECB, ID_NO_PADDING, const_cast<uint8_t*>(g_Prekey),
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);
294 ret = CCryptoEngine::Decrypt(dest, src, data_len, decryptedKeyBuffer, 0);
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);
312 // we have to check only UUID format
314 if (strlen(tmp_uuid) != 36) {
315 return SS_RET_INVALID_CREDENTIAL;
317 // checking delimiters
318 if (tmp_uuid[8] != '-' || tmp_uuid[13] != '-' || tmp_uuid[18] != '-'
319 || tmp_uuid[23] != '-') {
320 return SS_RET_INVALID_CREDENTIAL;
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'))
326 // return SS_RET_INVALID_CREDENTIAL;
328 // checking that string contains only hexidecimal values
329 if (-1 == is_hex(tmp_uuid, '-')) {
330 return SS_RET_INVALID_CREDENTIAL;
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;
340 return SS_RET_SUCCESS;
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;
349 return SS_RET_SUCCESS;
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;
360 return SS_RET_SUCCESS;
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;
369 if (SS_RET_SUCCESS != is_valid_options(options)) {
370 SLOGE("[%s] invalid options.\n", __FUNCTION__);
371 return SS_RET_INVALID_OPTIONS;
374 return SS_RET_SUCCESS;
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) {
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';
394 m_use_crypted_key = false;
396 m_cache = ss_temp_store::get_instance();
397 if (NULL == m_cache) {
398 SLOGF("[%s][%d](ERROR) Failed to alloc cache_manager. ", __FUNCTION__,
400 return SS_RET_MALLOC_FAILED;
403 return SS_RET_SUCCESS;
406 uint32_t secure_file::transform_name_to_id(const char* data_name) {
407 uint32_t uuidFile = 0;
409 for (unsigned int i = 0; i < strlen(data_name); i++) {
410 uuidFile = uuidFile * 33 + data_name[i];
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.
422 seed_rand(uDataFileID & 0xffffffff);
423 uDataFileName1 = gen_rand();
424 uDataFileName1 = (uDataFileName1 << 15) | (uDataFileName1 >> (32 - 15));
426 uDataFileName1 ^= gen_rand();
428 seed_rand((uDataFileID >> 32) & 0xffffffff);
429 uDataFileName2 = gen_rand();
430 uDataFileName2 = (uDataFileName2 << 10) | (uDataFileName2 >> (32 - 10));
432 uDataFileName2 ^= gen_rand();
433 // hexidecimal representation of return value will be the real file name.
434 uDataFileName = uDataFileName1 | (((uint64_t)uDataFileName2) << 32);
436 SLOGI("[%s][%d] uDataFileName : %llu", __FUNCTION__, __LINE__, (unsigned long long)uDataFileName);
437 return uDataFileName;
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;
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;
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;
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;
465 if (m_file_content.m_pOutputContent) {
466 delete[] m_file_content.m_pOutputContent;
467 m_file_content.m_pOutputContent = NULL;
470 if (m_is_partial_write) {
471 if (NULL != m_write_data) {
472 OsaFree(m_write_data);
477 OsaFree(m_read_data);
482 return SS_RET_SUCCESS;
485 int secure_file::derive_file_path() {
487 if (true == m_file_path_ready) {
488 return SS_RET_SUCCESS;
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;
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};
503 CBT_OCTET pHash[2 * CCryptoEngine::Hash_Size];
504 CBT_OCTET pFolderName[2 * CCryptoEngine::Hash_Size];
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);
512 memcpy(sUUID_and_Name, tmp_uuid, strlen(tmp_uuid));
513 memcpy(sUUID_and_Name + strlen(tmp_uuid), tmp_mn, strlen(tmp_mn));
515 // compute hash value of sUUID_and_Name
516 CCryptoEngine::Hash(pHash,
517 (CBT_OCTET*)sUUID_and_Name,
518 strlen(sUUID_and_Name));
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);
525 // concatenate with UUID and Name
526 //sTemp += sUUID_and_Name;
527 memcpy(sTemp + 2 * CCryptoEngine::Hash_Size,
529 strlen(sUUID_and_Name));
531 // compute hash of obtained string
532 CCryptoEngine::Hash(pHash, (CBT_OCTET*)sTemp, strlen(sTemp));
534 // we will use first 4 bytes of hash value
535 // convert them into hex format
536 //byte_to_hex(pFolderName, pHash, 4);
539 //sfolder.assign((char*)pFolderName, 8);
542 //m_full_path = sfolder;
543 memset(m_full_path, 0, SS_FULL_DATA_NAME_LEN);
544 memcpy(m_full_path, pHash, 4);
546 unsigned char dir[9] = {0};
547 byte_to_hex(dir, pHash, 4);
548 SLOGI("Dir is %s.", (char*)dir);
550 //m_full_path[8] = '/';
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));
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);
562 m_file_path_ready = true;
564 return SS_RET_SUCCESS;
568 void secure_file::compute_file_hash(CBT_OCTET* pHash) {
569 CryptoCoreContainer *crt = create_CryptoCoreContainer(ID_SHA1);
572 static_cast<cc_u8*>((void*)const_cast<uint8_t*>(m_file_content
573 .m_pFileContent)), m_file_content.m_uFileContentSize);
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);
581 int secure_file::prepare_file_content(unsigned char* buffer,
582 unsigned int buf_size) {
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];
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",
598 return SS_RET_MALLOC_FAILED;
600 m_file_content.m_bKeyAllocated = true;
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, ..)",
606 return SS_RET_MALLOC_FAILED;
609 m_file_content.m_bFileContentAllocated = true;
611 if (m_use_crypted_key) {
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),
619 m_file_content.m_pKeyMaterial,
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)",
627 SLOGF("[%s][%d](ERROR)", __FUNCTION__, __LINE__);
628 return SS_RET_INTERNAL_ERROR;
631 ret = CCryptoEngine::RSAEncrypt(m_file_content.m_EncryptedKeyBuffer + 4,
634 CCryptoEngine::Key_Size,
635 m_rsa_key.rsa_n_data,
637 m_rsa_key.rsa_e_data,
638 m_rsa_key.rsa_e_len);
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;
646 if (CRYPTO_SUCCESS != ret) {
647 SLOGD("%s RSA Encryption failure %i\n", __FUNCTION__, ret);
650 SLOGD("%s Content key size is = %ld\n", __FUNCTION__, uEncryptedKeySize);
654 m_file_content.m_uFileContentSize = Encrypt(m_file_content.m_pFileContent,
655 const_cast<CBT_OCTET*>(buffer),
657 m_file_content.m_pKeyMaterial,
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)",
664 SLOGF("[%s][%d](ERROR)", __FUNCTION__, __LINE__);
665 return SS_RET_INTERNAL_ERROR;
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;
674 if (!m_file_content.m_pHashMaterial) {
675 return SS_RET_MALLOC_FAILED;
678 m_file_content.m_bHashAllocated = true;
680 // filling it with random data
681 CCryptoEngine::Random(m_file_content.m_pHashMaterial, HASH_SIZE);
684 compute_file_hash(m_file_content.m_pHashMaterial);
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",
694 return SS_RET_MALLOC_FAILED;
697 m_file_content.m_bHeaderAllocated = true;
699 // filling it with random data
700 CCryptoEngine::Random(m_file_content.m_pFileHeader, HEADER_SIZE);
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;
708 if (m_use_crypted_key) {
709 m_file_content.m_pFileHeader[5] = 1; //encrypted key attached to file
711 m_file_content.m_pFileHeader[5] = 0;
714 SLOGI("[%s] m_file_content.m_pFileHeader[5] = %i",
716 m_file_content.m_pFileHeader[5]);
718 return SS_RET_SUCCESS;
722 int secure_file::parse_file_content(unsigned char* buffer,
723 unsigned int buf_size) {
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;
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",
740 SLOGD("[%s][%d](SS_RET_INVALID_FILE) *(pBuffer+1) : %c // %x",
745 return SS_RET_INVALID_FILE;
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",
755 SLOGD("[%s][%d](SS_RET_INVALID_FILE) *(pBuffer+3) : %c // %x",
760 return SS_RET_INVALID_FILE;
763 if ((buffer[4] != 1) || ((buffer[5] != 0) && (buffer[5] != 1))) {
764 SLOGD("[%s][%d](SS_RET_INVALID_FILE) *(pBuffer+4) : %c // %x",
769 SLOGD("[%s][%d](SS_RET_INVALID_FILE) *(pBuffer+5) : %c // %x",
774 return SS_RET_INVALID_FILE;
777 // temporary pointer to file content
778 CBT_OCTET* ptr = const_cast<CBT_OCTET*>(buffer);
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;
785 if (buffer[5] == 0) {
786 SLOGI("[%s][%d] File dosn't containe encrypted key material!",
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!",
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);
801 SLOGI("[%s][%d] m_file_content.m_uFileContentSize = %i!",
804 m_file_content.m_uFileContentSize);
805 SLOGI("[%s][%d] m_file_content.m_uEncryptedKeySize = %i!",
808 m_file_content.m_uEncryptedKeySize);
810 switch (FileStructureType(ptr)) {
812 // [header][hash][data][key]
813 m_file_content.m_pFileHeader = ptr;
815 m_file_content.m_pHashMaterial = ptr;
817 m_file_content.m_pFileContent = ptr;
818 ptr += m_file_content.m_uFileContentSize;
819 m_file_content.m_pKeyMaterial = ptr;
824 // [header][hash][key][data]
825 m_file_content.m_pFileHeader = ptr;
827 m_file_content.m_pHashMaterial = ptr;
829 m_file_content.m_pKeyMaterial = ptr;
831 m_file_content.m_pFileContent = ptr;
832 ptr += m_file_content.m_uFileContentSize;
836 // [header][data][key][hash]
837 m_file_content.m_pFileHeader = ptr;
839 m_file_content.m_pFileContent = ptr;
840 ptr += m_file_content.m_uFileContentSize;
841 m_file_content.m_pKeyMaterial = ptr;
843 m_file_content.m_pHashMaterial = ptr;
848 // [header][key][data][hash]
849 m_file_content.m_pFileHeader = ptr;
851 m_file_content.m_pKeyMaterial = ptr;
853 m_file_content.m_pFileContent = ptr;
854 ptr += m_file_content.m_uFileContentSize;
855 m_file_content.m_pHashMaterial = ptr;
860 // [header][key][hash][data]
861 m_file_content.m_pFileHeader = ptr;
863 m_file_content.m_pKeyMaterial = ptr;
865 m_file_content.m_pHashMaterial = ptr;
867 m_file_content.m_pFileContent = ptr;
868 ptr += m_file_content.m_uFileContentSize;
872 // [header][data][hash][key]
873 m_file_content.m_pFileHeader = ptr;
875 m_file_content.m_pFileContent = ptr;
876 ptr += m_file_content.m_uFileContentSize;
877 m_file_content.m_pHashMaterial = ptr;
879 m_file_content.m_pKeyMaterial = ptr;
884 SLOGD("[%s][%d](SS_RET_FAIL) OUT OF THE FileStructureType : %d",
887 FileStructureType(m_file_content.m_pFileHeader));
888 return SS_RET_INVALID_FILE;
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. ",
900 return SS_RET_MALLOC_FAILED;
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",
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",
926 m_file_content.m_uEncryptedKeySize);
927 return SS_RET_INVALID_FILE;
930 SLOGI("[%s][%d] Content key size is = %d",
933 m_file_content.m_uEncryptedKeySize);
935 SLOGI("[%s][%d] Decrypting content key", __FUNCTION__, __LINE__);
938 return SS_RET_SUCCESS;
942 int secure_file::serialize_data(unsigned char** buffer,
943 unsigned int& ret_size) {
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;
951 memcpy(*buffer, m_write_data, m_write_data_size);
952 ret_size = m_write_data_size;
953 return SS_RET_SUCCESS;
956 unsigned char* data = NULL;
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;
965 if (m_file_content.m_pFileHeader[5] == 1) {
966 buf_size += ENCRYPTED_KEY_SIZE;
969 data = (unsigned char*)OsaMalloc(buf_size + 1);
971 SLOGE("fail to alloc memory for data.");
972 return SS_RET_MALLOC_FAILED;
975 unsigned char* ptr = data;
976 switch (FileStructureType(m_file_content.m_pFileHeader)) {
978 // [header][hash][data][key]
979 memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
981 memcpy(ptr, m_file_content.m_pHashMaterial, HASH_SIZE);
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);
992 // [header][hash][key][data]
993 memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
995 memcpy(ptr, m_file_content.m_pHashMaterial, HASH_SIZE);
997 memcpy(ptr, m_file_content.m_pKeyMaterial, KEY_MAT_SIZE);
1000 m_file_content.m_pFileContent,
1001 m_file_content.m_uFileContentSize);
1002 ptr += m_file_content.m_uFileContentSize;
1006 // [header][data][key][hash]
1007 memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
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);
1020 // [header][key][data][hash]
1021 memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
1023 memcpy(ptr, m_file_content.m_pKeyMaterial, KEY_MAT_SIZE);
1024 ptr += KEY_MAT_SIZE;
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);
1034 // [header][key][hash][data]
1035 memcpy(ptr, m_file_content.m_pFileHeader, 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);
1042 m_file_content.m_pFileContent,
1043 m_file_content.m_uFileContentSize);
1044 ptr += m_file_content.m_uFileContentSize;
1048 // [header][data][hash][key]
1049 memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
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);
1057 memcpy(ptr, m_file_content.m_pKeyMaterial, KEY_MAT_SIZE);
1058 ptr += KEY_MAT_SIZE;
1062 SLOGD("[%s][%d](SS_RET_FAIL) OUT OF THE FileStructureType : %d",
1065 FileStructureType(m_file_content.m_pFileHeader));
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);
1078 ret_size = buf_size;
1080 return SS_RET_SUCCESS;
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__);
1092 return SS_RET_SUCCESS;
1095 int secure_file::write_persistent_store(unsigned char* data,
1096 unsigned int size) {
1098 char filename[MAX_FILENAME_LEN] = {0};
1099 get_data_name(filename, false);
1100 int iRet = file_op::write_file(filename, data, size);
1104 shm_manager shm_mgr;
1105 if (-1 == shm_mgr.init())
1107 SLOGE("Failed to init shm manager.");
1108 return SS_RET_COMM_ERR;
1112 req.type = REQ_WRITE;
1113 memcpy(req.data_name, m_full_path, SS_FULL_DATA_NAME_LEN);
1115 req.data_size = size;
1117 SLOGE("Data size = %d.", size);
1120 shm_mgr.put_request(&req);
1123 if (-1 == call_ta_service())
1125 SLOGE("Failed to call ta service.");
1126 return SS_RET_COMM_ERR;
1130 shm_mgr.get_response(&rsp);
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;
1142 return SS_RET_SUCCESS;
1145 int secure_file::read_persistent_store(unsigned char** buffer,
1146 unsigned int& ret_size) {
1148 char filename[MAX_FILENAME_LEN] = {0};
1149 get_data_name(filename, false);
1150 return file_op::read_file(filename, buffer, ret_size);
1153 shm_manager shm_mgr;
1154 if (-1 == shm_mgr.init())
1156 SLOGE("Failed to init shm manager.");
1157 return SS_RET_COMM_ERR;
1161 req.type = REQ_READ;
1162 memcpy(req.data_name, m_full_path, SS_FULL_DATA_NAME_LEN);
1167 shm_mgr.put_request(&req);
1169 if (-1 == call_ta_service())
1171 SLOGE("Failed to call ta service.");
1172 return SS_RET_COMM_ERR;
1176 shm_mgr.get_response(&rsp);
1178 if (SS_RET_SUCCESS != rsp.retcode)
1184 ret_size = rsp.data_size;
1186 SLOGI("ret_size = %d", ret_size);
1188 return SS_RET_SUCCESS;
1193 int secure_file::remove_persistent_store(bool is_dir) {
1195 char filename[MAX_FILENAME_LEN] = {0};
1196 get_data_name(filename, is_dir);
1197 int iret = SS_RET_SUCCESS;
1199 iret = file_op::remove_folder(filename);
1201 iret = file_op::remove_file(filename);
1208 shm_manager shm_mgr;
1209 if (-1 == shm_mgr.init())
1211 SLOGE("Failed to init shm manager.");
1212 return SS_RET_COMM_ERR;
1216 req.type = is_dir ? REQ_BATCH_REMOVE: REQ_REMOVE;
1217 memcpy(req.data_name, m_full_path, SS_FULL_DATA_NAME_LEN);
1222 shm_mgr.put_request(&req);
1224 if (-1 == call_ta_service())
1226 SLOGE("Failed to call ta service.");
1227 return SS_RET_COMM_ERR;
1231 shm_mgr.get_response(&rsp);
1237 int secure_file::check_file_content() {
1242 // compute file hash
1243 CBT_OCTET computed_hash[CCryptoEngine::Hash_Size];
1244 compute_file_hash(computed_hash);
1246 CBT_OCTET* stored_hash;
1247 stored_hash = m_file_content.m_pHashMaterial;
1249 if (memcmp(computed_hash, stored_hash, CCryptoEngine::Hash_Size)) {
1250 SLOGD("[%s][%d](SS_RET_INVALID_FILE) Hash is DIFFERENT!!!",
1253 return SS_RET_INVALID_FILE;
1256 return SS_RET_SUCCESS;
1260 int secure_file::decrypt_data() {
1262 m_file_content.m_pOutputContentSize = m_read_data_size;
1263 m_file_content.m_pOutputContent = m_read_data;
1268 if (m_use_crypted_key) {
1270 unsigned long uDecryptedKeySize;
1271 SLOGI("[%s][%d] Decrypting content key", __FUNCTION__, __LINE__);
1273 ret = CCryptoEngine::RSADecrypt(m_file_content.m_EncryptedKeyBuffer,
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);
1282 if (CRYPTO_SUCCESS != ret) {
1283 SLOGF("[%s][%d](SS_RET_FAIL) RSADecrypt failed!", __FUNCTION__, __LINE__);
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",
1293 return SS_RET_INVALID_FILE;
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);
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)",
1306 SLOGF("[%s][%d](ERROR)", __FUNCTION__, __LINE__);
1307 return SS_RET_INTERNAL_ERROR;
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,
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)",
1321 SLOGF("[%s][%d](ERROR)", __FUNCTION__, __LINE__);
1322 return SS_RET_INTERNAL_ERROR;
1326 return SS_RET_SUCCESS;
1330 secure_file::~secure_file() {
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)) {
1339 *ret_size = buf_size;
1340 return SS_RET_SUCCESS;
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;
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;
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)) {
1358 *ret_size = buf_size;
1359 m_is_partial_write = false;
1360 return SS_RET_SUCCESS;
1363 SLOGF("[%s][%d]Read data for partial write failed.", __FUNCTION__,
1368 if (offset > ori_size) {
1369 SLOGF("[%s][%d]offset(%d) exceed data size(%d).", __FUNCTION__, __LINE__,
1372 return SS_RET_OFFSET_ERR;
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);
1379 SLOGF("[%s][%d]Failed to alloc memory for data.", __FUNCTION__, __LINE__);
1381 return SS_RET_MALLOC_FAILED;
1384 unsigned char* dest = data;
1385 memcpy(dest, orig_data, offset);
1387 memcpy(dest, buffer, buf_size);
1390 if (0 == add_size) {
1391 memcpy(dest, orig_data + offset + buf_size, ori_size - offset - buf_size);
1395 *ret_size = ori_size + add_size;
1398 return SS_RET_SUCCESS;
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);
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;
1410 if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
1411 return SS_RET_INVALID_DATA_NAME;
1414 if (SS_MAX_DATA_SIZE < buf_size) {
1415 return SS_RET_DATA_SIZE_IS_TOO_BIG;
1418 memset(&m_file_content, 0, sizeof(m_file_content));
1420 int iRet = prepare_data(&m_write_data, &m_write_data_size, buffer, buf_size,
1422 if (SS_RET_SUCCESS != iRet) {
1423 SLOGF("[%s][%d]Failed to prepare data.", __FUNCTION__, __LINE__);
1427 SLOGE(" prepare_data data size = %d.", m_write_data_size);
1429 if (SS_MAX_DATA_SIZE < m_write_data_size) {
1430 SLOGF("[%s][%d]Data size %d is too big.", __FUNCTION__, __LINE__,
1432 return SS_RET_DATA_SIZE_IS_TOO_BIG;
1435 // generating new key material
1438 // preparing file content for writing
1439 ret = prepare_file_content(m_write_data, m_write_data_size);
1448 unsigned char* data = NULL;
1449 unsigned int size = 0;
1450 if (SS_RET_SUCCESS != (ret = serialize_data(&data, size))) {
1456 if (m_options & SS_OPT_TEMPORARY) {
1457 return write_temp_store(data, size);
1460 // writing data into file
1461 ret = write_persistent_store(data, size);
1466 int secure_file::read(unsigned char** ret_buf, unsigned int* read_size,
1467 unsigned int offset) {
1468 SLOGI("Entering secure_file::read");
1470 if (('\0' == m_data_name[0]) || (NULL == read_size)) {
1471 return SS_RET_INVALID_PARAM;
1474 if ((m_options & SS_OPT_PARTIAL_RW) && (0 == *read_size)) {
1475 SLOGE("Read zero byte data.");
1476 return SS_RET_INVALID_PARAM;
1479 if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
1480 return SS_RET_INVALID_DATA_NAME;
1485 unsigned int required_size = *read_size;
1486 unsigned int off_set = offset;
1489 // cleaning internal file structure representation
1490 memset(&m_file_content, 0, sizeof(m_file_content));
1494 // read from cache storage
1495 if (m_options & SS_OPT_TEMPORARY) {
1497 != (ret = read_temp_store(&m_read_data, m_read_data_size))) {
1498 SLOGE("[%s][%d](ERROR) Read data from temp store failed.", __FUNCTION__,
1503 ret = read_persistent_store(&m_read_data, m_read_data_size);
1510 ret = parse_file_content(m_read_data, m_read_data_size);
1515 // checking content integrity
1516 ret = check_file_content();
1522 ret = decrypt_data();
1524 SLOGE("[%s][%d](ERROR) DecryptData() // iRet : %d", __FUNCTION__, __LINE__,
1529 // partial rw not enabled.
1530 if (!(m_options & SS_OPT_PARTIAL_RW)) {
1532 required_size = m_file_content.m_pOutputContentSize + 1;
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;
1544 m_file_content.m_pOutputContentSize >= (off_set + required_size) ?
1545 required_size : (m_file_content.m_pOutputContentSize - off_set);
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;
1553 memcpy(*ret_buf, m_file_content.m_pOutputContent + off_set, ret_size);
1554 *read_size = ret_size;
1556 return SS_RET_SUCCESS;
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) {
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;
1570 if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
1571 return SS_RET_INVALID_DATA_NAME;
1574 if (SS_MAX_DATA_SIZE < buf_size) {
1575 return SS_RET_DATA_SIZE_IS_TOO_BIG;
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;
1584 // initiating special mode
1585 m_use_crypted_key = true;
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;
1595 // writing data into file
1596 ret = write(buffer, buf_size, offset);
1598 // removing special mode
1599 m_use_crypted_key = false;
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;
1612 if ((m_options & SS_OPT_PARTIAL_RW) && (0 == *read_size)) {
1613 SLOGE("Read zero byte data.");
1614 return SS_RET_INVALID_PARAM;
1617 if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
1618 return SS_RET_INVALID_DATA_NAME;
1623 // initiating special mode
1624 m_use_crypted_key = true;
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;
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;
1640 // writing data into file
1641 ret = read(ret_buf, read_size, offset);
1643 // removing special mode
1644 m_use_crypted_key = false;
1649 int secure_file::validate() {
1650 if ('\0' == m_data_name[0]) {
1651 return SS_RET_INVALID_PARAM;
1654 if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
1655 return SS_RET_INVALID_DATA_NAME;
1660 // cleaning internal file structure representation
1661 memset(&m_file_content, 0, sizeof(m_file_content));
1666 // read from cache storage
1667 if (m_options & SS_OPT_TEMPORARY) {
1669 != (ret = read_temp_store(&m_read_data, m_read_data_size))) {
1670 SLOGD("[%s][%d](ERROR) Read data from temp store failed.", __FUNCTION__,
1675 ret = read_persistent_store(&m_read_data, m_read_data_size);
1682 ret = parse_file_content(m_read_data, m_read_data_size);
1687 // checking content integrity
1688 return check_file_content();
1691 int secure_file::remove() {
1692 if ('\0' == m_data_name[0]) {
1693 return SS_RET_INVALID_PARAM;
1696 if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
1697 return SS_RET_INVALID_DATA_NAME;
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;
1708 return SS_RET_SUCCESS;
1711 return remove_persistent_store(false);
1714 int secure_file::clear_storage() {
1717 if (SS_OPT_TEMPORARY & m_options) {
1718 return m_cache->batch_remove(m_full_path);
1721 return remove_persistent_store(true);
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);
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';
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);
1745 //memcpy(ptr,m_full_path+SS_CRED_LEN,)
1746 //byte_to_hex(ptr, (uint8_t*)&m_full_path[4], 8);