2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 * @file FIo_SecureIoUtil.cpp
19 * @brief This is the implementation file for the %_SecureIoUilt class.
25 #include <sys/types.h>
32 #include <unique_ptr.h>
34 #include <FBaseString.h>
36 #include <FBaseResult.h>
37 #include <FSecSecretKey.h>
38 #include <FSecSecretKeyGenerator.h>
39 #include <FSecCryptoSha1Hash.h>
40 #include <FSecCryptoAesCipher.h>
42 #include <FBase_NativeError.h>
43 #include <FBaseSysLog.h>
44 #include <FBase_StringConverter.h>
45 #include <FIo_SecureIoUtil.h>
46 #include <FIo_FileUtil.h>
47 #include <FApp_AppInfo.h>
50 using namespace Tizen::Base;
51 using namespace Tizen::Security;
52 using namespace Tizen::Security::Crypto;
53 using namespace Tizen::App;
55 namespace Tizen { namespace Io
58 static const int SECURE_IO_4_BITS = 4;
59 static const int SECURE_IO_8_BITS = 8;
60 static const int SECURE_IO_3_BYTES = 3;
61 static const int SECURE_IO_9_BYTES = 9;
62 static const int SECURE_IO_HEX_0F = 0x0f;
63 static const int SECURE_IO_HEX_FC = 0xfc;
64 static const int SECURE_IO_HEX_FD = 0xfd;
65 static const int SECURE_IO_HEX_FE = 0xfe;
66 static const int SECURE_IO_HEX_FF = 0xff;
67 static const int DATABASE_KEY_LENGTH = 16;
68 static const int AES_KEY_LENGTH = 16;
70 const char SECURE_FILE_HEADER_STRING[] = {0x74, 0x69, 0x7a, 0x65, 0x6e, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x66, 0x69, 0x6c, 0x65};
71 const char SECURE_REG_HEADER_STRING[] = {0x74, 0x69, 0x7a, 0x65, 0x6e, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79};
72 static const wchar_t* _CIPHER_INFORMATION = L"CBC/128/NOPADDING";
75 _SecureIoUtil::GetSecureKeyN(const ByteBuffer* pUserKey)
79 unique_ptr< Tizen::Base::ByteBuffer > pKey(new (std::nothrow) ByteBuffer());
80 SysTryReturn(NID_IO, pKey != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
82 r = pKey->Construct(AES_KEY_LENGTH);
83 SysTryReturn(NID_IO, !IsFailed(r), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
85 if (pUserKey->GetRemaining() >= AES_KEY_LENGTH)
87 r = pKey->SetArray(pUserKey->GetPointer(), 0, AES_KEY_LENGTH);
88 SysTryReturn(NID_IO, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
94 int tempLength = pUserKey->GetRemaining();
95 int loopCount = AES_KEY_LENGTH / tempLength;
97 for(int i = 0; i < loopCount; i++)
100 r = pKey->SetArray(pUserKey->GetPointer(), 0, tempLength);
101 SysTryReturn(NID_IO, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
105 if (AES_KEY_LENGTH % tempLength)
107 r = pKey->SetArray(pUserKey->GetPointer(), 0, (AES_KEY_LENGTH % tempLength));
108 SysTryReturn(NID_IO, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
118 return pKey.release();
122 _SecureIoUtil::DoCipherAesN(const String transformation, const ByteBuffer& input, const ByteBuffer& key, CipherOperation encMode)
124 result r = E_SUCCESS;
127 SecretKeyGenerator secKeyGenerator;
129 static byte ivArray[] = {0x3E, 0xB5, 0x01, 0x45, 0xE4, 0xF8, 0x75, 0x3F, 0x08, 0x9D, 0x9F, 0x57, 0x3B, 0x63, 0xEF, 0x4B };
131 r = aesCipher.Construct(transformation, encMode);
132 SysTryReturn(NID_IO, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
134 r = ivBuffer.Construct(sizeof(ivArray));
135 SysTryReturn(NID_IO, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
137 r = ivBuffer.SetArray(ivArray, 0, sizeof(ivArray));
138 SysTryReturn(NID_IO, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
142 r = aesCipher.SetInitialVector(ivBuffer);
143 SysTryReturn(NID_IO, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
145 r = secKeyGenerator.Construct(key);
146 SysTryReturn(NID_IO, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
148 unique_ptr< ISecretKey > pKey(reinterpret_cast< ISecretKey* >(secKeyGenerator.GenerateKeyN()));
149 SysTryReturn(NID_IO, pKey != null, null, GetLastResult(), "[%s] Failed to generate key.", GetErrorMessage(GetLastResult()));
151 r = aesCipher.SetKey(*pKey.get());
152 SysTryReturn(NID_IO, !IsFailed(r), null, r, "[%s] Failed to set secret key.", GetErrorMessage(r));
154 unique_ptr< ByteBuffer > pOutBuf(null);
156 if (encMode == CIPHER_ENCRYPT)
158 pOutBuf = unique_ptr< ByteBuffer >(aesCipher.EncryptN(input));
162 pOutBuf = unique_ptr< ByteBuffer >(aesCipher.DecryptN(input));
165 SysTryReturn(NID_IO, pOutBuf != null, null, GetLastResult(), "[%s] Failed to decrypt data.", GetErrorMessage(GetLastResult()));
167 SetLastResult(E_SUCCESS);
168 return pOutBuf.release();
172 _SecureIoUtil::IsEndOfFile(_NormalFile* pNormalFile)
174 result r = E_SUCCESS;
177 int current = pNormalFile->Tell();
178 SysTryReturn(NID_IO, current != -1, false, GetLastResult(), "[%s] Failed to tell in file.", GetErrorMessage(GetLastResult()));
180 int ret = pNormalFile->Read(&flag, 1); //ignore ret as we are only looking for EOF.
181 if (GetLastResult() == E_END_OF_FILE && ret == 0)
186 r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, current);
187 SysTryReturn(NID_IO, !IsFailed(r), false, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
193 _SecureIoUtil::InsertSecureFileHeader(_NormalFile* pNormalFile)
195 result r = E_SUCCESS;
197 byte secureHeader[SECURE_FILE_HEADER_SIZE_V1];
198 byte reservedValue[SECURE_IO_STATIC_BIN_LEN] = {0xCA, 0xFE, 0xBE, 0xBE, 0xDA, 0xEF, 0xEB, 0xEB};
201 r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, 0);
202 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
204 ret = pNormalFile->Read(secureHeader, SECURE_FILE_HEADER_SIZE_V1);
205 if (ret < SECURE_FILE_HEADER_SIZE_V1)
209 if (ret == 0 && IsEndOfFile(pNormalFile)) //is true
211 memcpy(secureHeader, SECURE_FILE_HEADER_STRING, SECURE_FILE_HEADER_STRING_SIZE);
212 memcpy(secureHeader + SECURE_FILE_HEADER_STRING_SIZE, reservedValue, SECURE_IO_STATIC_BIN_LEN);
213 secureHeader[SECURE_FILE_HEADER_STRING_SIZE + SECURE_IO_STATIC_BIN_LEN] = SECURE_IO_2_BYTES;
214 secureHeader[SECURE_FILE_HEADER_STRING_SIZE + SECURE_IO_STATIC_BIN_LEN + SECURE_IO_FLAG_SIZE] = 0;
215 memset(secureHeader + SECURE_FILE_HEADER_STRING_SIZE + SECURE_IO_STATIC_BIN_LEN + SECURE_IO_FLAG_SIZE + SECURE_IO_INDEX_SIZE, 0, SECURE_IO_LOF_SIZE);
216 memset(secureHeader + SECURE_FILE_HEADER_STRING_SIZE + SECURE_IO_STATIC_BIN_LEN + SECURE_IO_FLAG_SIZE + SECURE_IO_INDEX_SIZE + SECURE_IO_LOF_SIZE, 0, SECURE_IO_LOF_SIZE);
218 r = pNormalFile->Write(secureHeader, SECURE_FILE_HEADER_SIZE_V1);
219 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] [%s] Failed to write in file.", GetErrorMessage(r));
224 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
226 } //Else it means that header is already written
232 _SecureIoUtil::SaveLengthOfFile(_NormalFile* pNormalFile)
234 result r = E_SUCCESS;
236 byte lengthOfFile[SECURE_IO_LOF_SIZE] = {0, 0, 0, 0};
239 r = pNormalFile->Seek(FILESEEKPOSITION_END, 0);
240 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
242 length = pNormalFile->Tell();
243 SysTryReturn(NID_IO, length != -1, GetLastResult(), GetLastResult(), "[%s] Failed to tell in file.", GetErrorMessage(GetLastResult()));
245 r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, SECURE_FILE_HEADER_STRING_SIZE + SECURE_IO_10_BYTES);
246 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
248 if (sizeof(length) != SECURE_IO_LOF_SIZE)
250 memcpy(lengthOfFile + SECURE_IO_LOF_SIZE - sizeof(length), &length, sizeof(length));
254 memcpy(lengthOfFile, &length, SECURE_IO_LOF_SIZE);
257 r = pNormalFile->Write(lengthOfFile, SECURE_IO_LOF_SIZE);
258 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to write in file.", GetErrorMessage(r));
264 _SecureIoUtil::SelectCipherBlock(_NormalFile* pNormalFile, long virtualFilePointer, int* pPosition)
266 result r = E_SUCCESS;
270 long blockDataSize = 0;
271 byte secureHeader[SECURE_FILE_HEADER_SIZE_V1] = {0, };
272 byte blockHeader[CIPHER_BLOCK_HEADER_SIZE] = {0, 0, 0};
273 byte* pBlockDataCur = null;
276 r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, 0);
279 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
281 ret = pNormalFile->Read(secureHeader, SECURE_FILE_HEADER_SIZE_V1);
282 if (ret < SECURE_FILE_HEADER_SIZE_V1)
286 if (ret == 0 && IsEndOfFile(pNormalFile))
291 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
295 //read 1byte to check padding size
298 r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, count * (CIPHER_BLOCK_SIZE + CIPHER_BLOCK_HEADER_SIZE) + SECURE_FILE_HEADER_SIZE_V1);
299 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
301 ret = pNormalFile->Read(blockHeader, CIPHER_BLOCK_HEADER_SIZE);
302 if (ret < CIPHER_BLOCK_HEADER_SIZE) //less data read
306 if (ret == 0 && IsEndOfFile(pNormalFile))
311 SysLog(NID_IO, "[%s] Failed to read data from file", GetErrorMessage(r));
317 pBlockDataCur = (byte*) (&blockDataSize);
318 *pBlockDataCur = blockHeader[SECURE_IO_2_BYTES];
319 *(pBlockDataCur + 1) = blockHeader[1];
320 *(pBlockDataCur + SECURE_IO_2_BYTES) = blockHeader[0];
322 if (virtualFilePointer <= dataSize + blockDataSize)
324 *pPosition = virtualFilePointer - dataSize;
325 if (*pPosition == CIPHER_BLOCK_SIZE)
327 r = pNormalFile->Seek(FILESEEKPOSITION_CURRENT, CIPHER_BLOCK_SIZE);
332 r = pNormalFile->Seek(FILESEEKPOSITION_CURRENT, -CIPHER_BLOCK_HEADER_SIZE);
336 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
341 dataSize = dataSize + blockDataSize;
351 _SecureIoUtil::DetectNewLine(byte* pData, int readSize, int preReadSize, int* pTerminationCur, int* newLineSize)
357 for (count = preReadSize; count < readSize; count++)
359 if (pData[count] == '\r' && pData[count + 1] == '\n')
361 *pTerminationCur = count;
362 *newLineSize = SECURE_IO_2_BYTES;
366 if (pData[count] == '\n')
368 *pTerminationCur = count;
378 _SecureIoUtil::MakeCipherBlock(byte* pData, int dataSize, byte** ppEncryptedData, int* pEncryptedDataSize, const ByteBuffer& key)
380 result r = E_SUCCESS;
382 int lastDataSize = 0;
385 byte* pTempRealloc = null;
386 byte* pTempEncryptedData = null;
389 SysTryReturnResult(NID_SEC, dataSize > 0, E_INVALID_ARG, "Input data is not valid.");
392 *pEncryptedDataSize = 0;
394 blockCount = dataSize / CIPHER_BLOCK_SIZE;
395 lastDataSize = dataSize % CIPHER_BLOCK_SIZE;
396 if (lastDataSize != 0)
398 blockCount = blockCount + 1;
402 lastDataSize = CIPHER_BLOCK_SIZE;
405 for (int i = 0; i < blockCount; i++)
407 if (i == blockCount - 1)
409 tempSize = lastDataSize;
413 tempSize = CIPHER_BLOCK_SIZE;
416 inputSize = tempSize;
418 if (tempSize % ONE_BLOCK_SIZE != 0)
420 tempSize = (tempSize / ONE_BLOCK_SIZE) * ONE_BLOCK_SIZE + ONE_BLOCK_SIZE;
423 r = input.Construct(tempSize);
424 SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Propagated.", GetErrorMessage(r));
426 r = input.SetArray((byte*) (pData + i * CIPHER_BLOCK_SIZE), 0, inputSize);
427 SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Propagated.", GetErrorMessage(r));
429 if (inputSize < tempSize)
431 unique_ptr< char[] > pFill(new (std::nothrow) char[tempSize - inputSize]);
432 SysTryCatch(NID_IO, pFill != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
434 memset(pFill.get(), 0, tempSize - inputSize);
436 r = input.SetArray(reinterpret_cast< byte* >(pFill.get()), 0, tempSize - inputSize);
437 SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Propagated.", GetErrorMessage(r));
443 unique_ptr< ByteBuffer > pEncryptedBuffer(DoCipherAesN(_CIPHER_INFORMATION, input, key, CIPHER_ENCRYPT));
444 SysTryCatch(NID_IO, pEncryptedBuffer != null, r = E_IO, E_IO, "[E_IO] Failed to encrypt data.");
446 pTempEncryptedData = const_cast< byte* >(pEncryptedBuffer->GetPointer());
447 SysTryCatch(NID_IO, pTempEncryptedData != null, , r, "[%s] Failed to get encrypted data.", GetErrorMessage(r));
449 pTempRealloc = (byte*) new (std::nothrow) byte[*pEncryptedDataSize + tempSize + CIPHER_BLOCK_HEADER_SIZE];
450 SysTryCatch(NID_IO, pTempRealloc != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
452 if (*ppEncryptedData)
454 memcpy(pTempRealloc, *ppEncryptedData, *pEncryptedDataSize);
456 delete[]* ppEncryptedData;
457 *ppEncryptedData = null;
460 *ppEncryptedData = pTempRealloc;
462 if (i == blockCount - 1)
465 *(*ppEncryptedData + i * (CIPHER_BLOCK_SIZE + CIPHER_BLOCK_HEADER_SIZE) + SECURE_IO_2_BYTES) \
466 = (byte) (lastDataSize & SECURE_IO_HEX_FF);
467 *(*ppEncryptedData + i * (CIPHER_BLOCK_SIZE + CIPHER_BLOCK_HEADER_SIZE) + 1) \
468 = (byte) ((lastDataSize >> SECURE_IO_8_BITS) & SECURE_IO_HEX_FF);
469 *(*ppEncryptedData + i * (CIPHER_BLOCK_SIZE + CIPHER_BLOCK_HEADER_SIZE)) \
470 = (byte) ((lastDataSize >> (SECURE_IO_8_BITS * SECURE_IO_2_BYTES)) & SECURE_IO_HEX_FF);
474 *(*ppEncryptedData + i * (CIPHER_BLOCK_SIZE + CIPHER_BLOCK_HEADER_SIZE) + SECURE_IO_2_BYTES) \
475 = (byte) (CIPHER_BLOCK_SIZE & SECURE_IO_HEX_FF);
476 *(*ppEncryptedData + i * (CIPHER_BLOCK_SIZE + CIPHER_BLOCK_HEADER_SIZE) + 1) \
477 = (byte) ((CIPHER_BLOCK_SIZE >> SECURE_IO_8_BITS) & SECURE_IO_HEX_FF);
478 *(*ppEncryptedData + i * (CIPHER_BLOCK_SIZE + CIPHER_BLOCK_HEADER_SIZE)) \
479 = (byte) ((CIPHER_BLOCK_SIZE >> (SECURE_IO_8_BITS * SECURE_IO_2_BYTES)) & SECURE_IO_HEX_FF);
482 memcpy(*ppEncryptedData + i * (CIPHER_BLOCK_SIZE + CIPHER_BLOCK_HEADER_SIZE) + CIPHER_BLOCK_HEADER_SIZE, pTempEncryptedData, tempSize);
483 *pEncryptedDataSize = *pEncryptedDataSize + tempSize + CIPHER_BLOCK_HEADER_SIZE;
490 *pEncryptedDataSize = 0;
491 delete[]* ppEncryptedData;
492 *ppEncryptedData = null;
499 _SecureIoUtil::WriteDataInCipherBlock(_NormalFile* pNormalFile, int dataPosition, bool eofSet, int dataSize, byte* pData, const ByteBuffer& key)
501 result r = E_SUCCESS;
502 int availableSize = 0;
503 int encryptedDataSize = 0;
505 long blockDataSize = 0;
506 long tempBlockDataSize = 0;
507 bool isFirstBlockSet = false;
508 byte* pBlockDataCur = null;
509 byte* pCipherBlockData = null;
510 byte* pDataPos = null;
511 byte blockHeader[CIPHER_BLOCK_HEADER_SIZE] = {0, 0, 0};
519 if (eofSet != false && dataPosition == 0)
521 r = MakeCipherBlock(pDataPos, dataSize, &pCipherBlockData, &encryptedDataSize, key);
522 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to make cipher block for file.", GetErrorMessage(r));
524 unique_ptr< byte[] > pEncryptedBlockData(pCipherBlockData);
525 pCipherBlockData = null;
527 SysTryReturn(NID_IO, pEncryptedBlockData != null, r, r, "[%s] Failed to make cipher block for file.", GetErrorMessage(r));
529 r = pNormalFile->Write(pEncryptedBlockData.get(), encryptedDataSize);
530 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to make cipher block for file.", GetErrorMessage(r));
535 ret = pNormalFile->Read(blockHeader, CIPHER_BLOCK_HEADER_SIZE);
536 if (ret < CIPHER_BLOCK_HEADER_SIZE)
540 if (ret == 0 && IsEndOfFile(pNormalFile))
545 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
550 pBlockDataCur = (byte*) (&blockDataSize);
551 *pBlockDataCur = blockHeader[SECURE_IO_2_BYTES];
552 *(pBlockDataCur + 1) = blockHeader[1];
553 *(pBlockDataCur + SECURE_IO_2_BYTES) = blockHeader[0];
555 unique_ptr< byte[] > pTempEncryptedData(new (std::nothrow) byte[CIPHER_BLOCK_SIZE]);
556 SysTryReturnResult(NID_IO, pTempEncryptedData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
558 memset(pTempEncryptedData.get(), 0, CIPHER_BLOCK_SIZE);
560 if (blockDataSize % ONE_BLOCK_SIZE != 0)
562 tempBlockDataSize = blockDataSize + ONE_BLOCK_SIZE - blockDataSize % ONE_BLOCK_SIZE;
566 tempBlockDataSize = blockDataSize;
569 ret = pNormalFile->Read(pTempEncryptedData.get(), tempBlockDataSize);
570 if (ret < tempBlockDataSize)
574 if (ret == 0 && IsEndOfFile(pNormalFile))
579 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
583 r = input.Construct(tempBlockDataSize);
584 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
586 r = input.SetArray(pTempEncryptedData.get(), 0, tempBlockDataSize);
588 pTempEncryptedData.reset(null);
590 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
594 unique_ptr< ByteBuffer > pDecryptedBuffer(DoCipherAesN(_CIPHER_INFORMATION, input, key, CIPHER_DECRYPT));
595 SysTryReturn(NID_IO, pDecryptedBuffer != null, E_IO, E_IO, "[E_IO] Failed to encrypt data.");
597 unique_ptr< byte[] > pDecryptedBlockData(new (std::nothrow) byte[tempBlockDataSize]);
598 SysTryReturnResult(NID_IO, pDecryptedBlockData != null, E_OUT_OF_MEMORY, "The memory is insufficient");
600 r = pDecryptedBuffer->GetArray(reinterpret_cast< byte* >(pDecryptedBlockData.get()), 0, tempBlockDataSize);
601 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to get decrypted buffer.", GetErrorMessage(r));
603 pDecryptedBuffer->Flip();
605 pDecryptedBuffer.reset(null);
607 if (isFirstBlockSet == false)
609 availableSize = CIPHER_BLOCK_SIZE - dataPosition;
610 if (availableSize >= dataSize)
612 if (tempBlockDataSize < dataPosition + dataSize)
614 unique_ptr< byte[] > pTempRealloc(new (std::nothrow) byte[dataPosition + dataSize]);
615 SysTryReturnResult(NID_IO, pTempRealloc != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
617 memcpy(pTempRealloc.get(), pDecryptedBlockData.get(), tempBlockDataSize);
619 pDecryptedBlockData.reset(null);
620 pDecryptedBlockData = move(pTempRealloc);
623 memcpy(reinterpret_cast< byte* >(pDecryptedBlockData.get()) + dataPosition, pDataPos, dataSize);
625 if (blockDataSize < dataPosition + dataSize)
627 r = MakeCipherBlock(pDecryptedBlockData.get(), dataPosition + dataSize, &pCipherBlockData, &encryptedDataSize, key);
631 r = MakeCipherBlock(pDecryptedBlockData.get(), blockDataSize, &pCipherBlockData, &encryptedDataSize, key);
634 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to make cipher block for file.", GetErrorMessage(r));
636 unique_ptr< byte[] > pEncryptedBlockData(pCipherBlockData);
637 pCipherBlockData = null;
639 SysTryReturn(NID_IO, pEncryptedBlockData != null, r, r, "[%s] Failed to make cipher block for file.", GetErrorMessage(r));
641 r = pNormalFile->Seek(FILESEEKPOSITION_CURRENT, -(tempBlockDataSize + CIPHER_BLOCK_HEADER_SIZE));
642 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
644 r = pNormalFile->Write(pEncryptedBlockData.get(), encryptedDataSize);
645 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to write in file.", GetErrorMessage(r));
650 else //(availableSize < dataSize)
652 if (tempBlockDataSize < dataPosition + availableSize)
654 unique_ptr< byte[] > pTempRelloc(new (std::nothrow) byte[dataPosition + availableSize]);
655 SysTryReturnResult(NID_IO, pTempRelloc != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
657 memcpy(pTempRelloc.get(), pDecryptedBlockData.get(), tempBlockDataSize);
659 pDecryptedBlockData.reset(null);
660 pDecryptedBlockData = move(pTempRelloc);
663 memcpy(reinterpret_cast< byte* >(pDecryptedBlockData.get()) + dataPosition, pDataPos, availableSize);
665 pDataPos = pDataPos + availableSize;
666 dataSize = dataSize - availableSize;
668 r = MakeCipherBlock(pDecryptedBlockData.get(), CIPHER_BLOCK_SIZE, &pCipherBlockData, &encryptedDataSize, key);
669 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to make cipher block for file.", GetErrorMessage(r));
671 unique_ptr< byte[] > pEncryptedBlockData(pCipherBlockData);
672 pCipherBlockData = null;
673 SysTryReturn(NID_IO, pEncryptedBlockData != null, r, r, "[%s] Failed to make cipher block for file.", GetErrorMessage(r));
675 r = pNormalFile->Seek(FILESEEKPOSITION_CURRENT, -(tempBlockDataSize + CIPHER_BLOCK_HEADER_SIZE));
676 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
678 r = pNormalFile->Write(pEncryptedBlockData.get(), encryptedDataSize);
679 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to write in file.", GetErrorMessage(r));
685 isFirstBlockSet = true;
689 availableSize = CIPHER_BLOCK_SIZE;
690 if (availableSize >= dataSize)
692 if (tempBlockDataSize < dataSize)
694 unique_ptr< byte[] > pTempRelloc(new (std::nothrow) byte[dataSize]);
695 SysTryReturnResult(NID_IO, pTempRelloc != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
697 memcpy(pTempRelloc.get(), pDecryptedBlockData.get(), tempBlockDataSize);
699 pDecryptedBlockData.reset(null);
700 pDecryptedBlockData = move(pTempRelloc);
703 memcpy(pDecryptedBlockData.get(), pDataPos, dataSize);
705 if (blockDataSize < dataPosition + dataSize)
707 r = MakeCipherBlock(pDecryptedBlockData.get(), dataSize, &pCipherBlockData, &encryptedDataSize, key);
711 r = MakeCipherBlock(pDecryptedBlockData.get(), blockDataSize, &pCipherBlockData, &encryptedDataSize, key);
714 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to make cipher block for file.", GetErrorMessage(r));
716 unique_ptr< byte[] > pEncryptedBlockData(pCipherBlockData);
717 pCipherBlockData = null;
719 SysTryReturn(NID_IO, pEncryptedBlockData != null, r, r, "[%s] Failed to make cipher block for file.", GetErrorMessage(r));
721 r = pNormalFile->Seek(FILESEEKPOSITION_CURRENT, -(tempBlockDataSize + CIPHER_BLOCK_HEADER_SIZE));
722 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
724 r = pNormalFile->Write(pEncryptedBlockData.get(), encryptedDataSize);
725 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to write in file.", GetErrorMessage(r));
729 else //availableSize < dataSize
731 if (tempBlockDataSize < availableSize)
733 unique_ptr< byte[] > pTempRelloc(new (std::nothrow) byte[availableSize]);
734 SysTryReturnResult(NID_IO, pTempRelloc != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
736 memcpy(pTempRelloc.get(), pDecryptedBlockData.get(), tempBlockDataSize);
738 pDecryptedBlockData.reset(null);
739 pDecryptedBlockData = move(pTempRelloc);
742 memcpy(pDecryptedBlockData.get(), pDataPos, availableSize);
744 pDataPos = pDataPos + availableSize;
745 dataSize = dataSize - availableSize;
747 r = MakeCipherBlock(pDecryptedBlockData.get(), CIPHER_BLOCK_SIZE, &pCipherBlockData, &encryptedDataSize, key);
748 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to make cipher block for file.", GetErrorMessage(r));
750 unique_ptr< byte[] > pEncryptedBlockData(pCipherBlockData);
751 pCipherBlockData = null;
753 SysTryReturn(NID_IO, pEncryptedBlockData != null, r, r, "[%s] Failed to make cipher block for file.", GetErrorMessage(r));
755 r = pNormalFile->Seek(FILESEEKPOSITION_CURRENT, -(tempBlockDataSize + CIPHER_BLOCK_HEADER_SIZE));
756 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
758 r = pNormalFile->Write(pEncryptedBlockData.get(), encryptedDataSize);
759 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to write in file.", GetErrorMessage(r));
766 eofSet = IsEndOfFile(pNormalFile);
773 _SecureIoUtil::ReadDataFromCipherBlock(_NormalFile* pNormalFile, int dataPosition, int bufferSize, byte* pData, _DataFormat dataMode, int* readItems, const ByteBuffer& key)
775 result r = E_SUCCESS;
778 int terminationCur = 0;
782 long blockDataSize = 0;
783 long tempBlockDataSize = 0;
784 byte* pBlockDataCur = null;
785 byte* pDecryptedBlockData = null;
786 byte blockHeader[CIPHER_BLOCK_HEADER_SIZE] = {0, 0, 0};
790 ret = pNormalFile->Read(blockHeader, CIPHER_BLOCK_HEADER_SIZE);
791 if (ret < CIPHER_BLOCK_HEADER_SIZE)
795 if (ret == 0 && IsEndOfFile(pNormalFile))
800 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
805 pBlockDataCur = (byte*) (&blockDataSize);
806 *pBlockDataCur = blockHeader[SECURE_IO_2_BYTES];
807 *(pBlockDataCur + 1) = blockHeader[1];
808 *(pBlockDataCur + SECURE_IO_2_BYTES) = blockHeader[0];
810 unique_ptr< byte[] > pBlockData(new (std::nothrow) byte[CIPHER_BLOCK_SIZE]);
811 SysTryReturnResult(NID_IO, pBlockData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
813 memset(pBlockData.get(), 0, CIPHER_BLOCK_SIZE);
815 if (blockDataSize % ONE_BLOCK_SIZE != 0)
817 tempBlockDataSize = blockDataSize + ONE_BLOCK_SIZE - blockDataSize % ONE_BLOCK_SIZE;
821 tempBlockDataSize = blockDataSize;
824 ret = pNormalFile->Read(pBlockData.get(), tempBlockDataSize);
825 if (ret < tempBlockDataSize)
829 if (ret == 0 && IsEndOfFile(pNormalFile))
834 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
838 readingSize = blockDataSize - dataPosition;
839 SysTryReturn(NID_IO, readingSize != 0, r = E_END_OF_FILE, r, "[%s] Failed to get positive value of readingSize.", GetErrorMessage(r));
841 r = input.Construct(tempBlockDataSize);
842 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
844 r = input.SetArray(pBlockData.get(), 0, tempBlockDataSize);
845 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
849 unique_ptr< ByteBuffer > pDecryptedBuffer(DoCipherAesN(_CIPHER_INFORMATION, input, key, CIPHER_DECRYPT));
850 SysTryReturn(NID_IO, pDecryptedBuffer != null, E_IO, E_IO, "[E_IO] Failed to encrypt data.");
852 pDecryptedBlockData = const_cast< byte* >(pDecryptedBuffer->GetPointer());
853 SysTryReturn(NID_IO, pDecryptedBlockData, r, r, "[%s] Failed to get encrypted data.", GetErrorMessage(r));
855 unique_ptr< byte[] > pTemp(new (std::nothrow) byte[readingSize]);
856 SysTryReturnResult(NID_IO, pTemp != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
858 memcpy(pTemp.get(), pDecryptedBlockData + dataPosition, readingSize);
860 pDecryptedBuffer.reset(null);
864 eofSet = IsEndOfFile(pNormalFile);
866 if (dataMode == DATA_FORMAT_BYTE && (readingSize >= bufferSize))
868 memcpy(pData, pTemp.get(), bufferSize);
869 *readItems = bufferSize;
872 else if (dataMode == DATA_FORMAT_STRING && ((readingSize >= bufferSize) || DetectNewLine(pTemp.get(), readingSize, tempSize, &terminationCur, &newLineSize)))
874 if (terminationCur != 0)
876 memcpy(pData, pTemp.get(), terminationCur);
877 *(pData + terminationCur) = '\n';
878 *readItems = terminationCur + newLineSize;
882 memcpy(pData, pTemp.get(), bufferSize);
883 *readItems = bufferSize;
887 else if (eofSet && (readingSize < bufferSize))
889 memcpy(pData, pTemp.get(), readingSize);
890 *readItems = readingSize;
895 ret = pNormalFile->Read(blockHeader, CIPHER_BLOCK_HEADER_SIZE);
896 if (ret < CIPHER_BLOCK_HEADER_SIZE)
900 if (ret == 0 && IsEndOfFile(pNormalFile))
906 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
911 pBlockDataCur = (byte*) (&blockDataSize);
912 *pBlockDataCur = blockHeader[SECURE_IO_2_BYTES];
913 *(pBlockDataCur + 1) = blockHeader[1];
914 *(pBlockDataCur + SECURE_IO_2_BYTES) = blockHeader[0];
916 memset(pBlockData.get(), 0, CIPHER_BLOCK_SIZE);
918 if (blockDataSize % ONE_BLOCK_SIZE != 0)
920 tempBlockDataSize = blockDataSize + ONE_BLOCK_SIZE - blockDataSize % ONE_BLOCK_SIZE;
924 tempBlockDataSize = blockDataSize;
927 ret = pNormalFile->Read(pBlockData.get(), tempBlockDataSize);
928 if (ret < tempBlockDataSize)
932 if (ret == 0 && IsEndOfFile(pNormalFile))
937 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
941 r = input.Construct(tempBlockDataSize);
942 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
944 r = input.SetArray(pBlockData.get(), 0, tempBlockDataSize);
945 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
949 unique_ptr< ByteBuffer > pDecryptedNextBuffer(DoCipherAesN(_CIPHER_INFORMATION, input, key, CIPHER_DECRYPT));
950 SysTryReturn(NID_IO, pDecryptedNextBuffer != null, E_IO, E_IO, "[E_IO] Failed to encrypt data.");
952 pDecryptedBlockData = const_cast< byte* >(pDecryptedNextBuffer->GetPointer());
953 SysTryReturn(NID_IO, pDecryptedBlockData != null, r, r, "[%s] Failed to get encrypted data.", GetErrorMessage(r));
955 tempSize = readingSize;
956 readingSize = readingSize + blockDataSize;
958 unique_ptr< byte[] > pTempRealloc(new (std::nothrow) byte[readingSize]);
959 SysTryReturnResult(NID_IO, pTempRealloc != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
961 memcpy(pTempRealloc.get(), pTemp.get(), tempSize);
964 pTemp = move(pTempRealloc);
966 memcpy(reinterpret_cast< byte* >(pTemp.get()) + tempSize, pDecryptedBlockData, blockDataSize);
975 _SecureIoUtil::GetDataLengh(_NormalFile* pNormalFile, long int* dataLength)
977 result r = E_SUCCESS;
979 long blockDataSize = 0;
980 byte* pBlockDataCur = null;
981 byte secureHeader[SECURE_FILE_HEADER_SIZE_V1];
982 byte blockHeader[CIPHER_BLOCK_HEADER_SIZE] = {0, 0, 0};
987 r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, 0);
988 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
990 ret = pNormalFile->Read(secureHeader, SECURE_FILE_HEADER_SIZE_V1);
991 if (ret < SECURE_FILE_HEADER_SIZE_V1)
995 if (ret == 0 && IsEndOfFile(pNormalFile))
1000 SysLog(NID_IO, "[%s] Failed to seek in file", GetErrorMessage(r));
1005 ret = pNormalFile->Read(blockHeader, CIPHER_BLOCK_HEADER_SIZE);
1006 if (ret < CIPHER_BLOCK_HEADER_SIZE)
1008 r = GetLastResult();
1010 if (ret == 0 && IsEndOfFile(pNormalFile))
1016 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
1021 pBlockDataCur = (byte*) (&blockDataSize);
1022 *pBlockDataCur = blockHeader[SECURE_IO_2_BYTES];
1023 *(pBlockDataCur + 1) = blockHeader[1];
1024 *(pBlockDataCur + SECURE_IO_2_BYTES) = blockHeader[0];
1025 *dataLength = *dataLength + blockDataSize;
1027 if (blockDataSize % ONE_BLOCK_SIZE != 0)
1029 r = pNormalFile->Seek(FILESEEKPOSITION_CURRENT, blockDataSize + ONE_BLOCK_SIZE - blockDataSize % ONE_BLOCK_SIZE);
1033 r = pNormalFile->Seek(FILESEEKPOSITION_CURRENT, blockDataSize);
1036 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
1040 return pNormalFile->Seek(FILESEEKPOSITION_END, 0);
1044 _SecureIoUtil::CheckSecureFileHeader(const Tizen::Base::String& filePath, const ByteBuffer* pSecretKey)
1046 byte secureFileHeader[SECURE_FILE_HEADER_SIZE_V1] = { 0, };
1047 byte reservedValue[SECURE_IO_STATIC_BIN_LEN] = { 0xCA, 0xFE, 0xBE, 0xBE, 0xDA, 0xEF, 0xEB, 0xEB };
1049 _NormalFile normalFile;
1050 result r = normalFile.Construct(filePath, "r");
1051 SysTryReturnResult(NID_IO, !IsFailed(r), r, "Failed to open the file (%ls).", filePath.GetPointer());
1053 int ret = normalFile.Read(secureFileHeader, SECURE_FILE_HEADER_SIZE_V1);
1054 if (ret < SECURE_FILE_HEADER_SIZE_V1)
1056 r = GetLastResult();
1057 if (IsEndOfFile(&normalFile))
1059 if (ret && pSecretKey)
1071 // Checks if the file is encrypted file. (in normal or secure mode)
1072 ret = memcmp(secureFileHeader, SECURE_FILE_HEADER_STRING, SECURE_FILE_HEADER_STRING_SIZE);
1073 ret |= memcmp(secureFileHeader + SECURE_FILE_HEADER_STRING_SIZE, reservedValue, SECURE_IO_STATIC_BIN_LEN);
1074 SysTryReturnResult(NID_IO, !(ret && pSecretKey), E_INVALID_ARG, "Failed to match secure header in file.");
1082 _SecureIoUtil::SetRegistryFlag(void* pFileSecure, _FlagState flag)
1084 result r = E_SUCCESS;
1087 byte currentFlag = 0;
1088 _FileImpl* pFile = (_FileImpl*) pFileSecure;
1091 current = pFile->Tell();
1092 SysTryReturn(NID_IO, current != -1, GetLastResult(), GetLastResult(), "[%s] Tell file has failed.", GetErrorMessage(GetLastResult()));
1094 r = pFile->Seek(FILESEEKPOSITION_BEGIN, SECURE_REG_HEADER_STRING_SIZE + SECURE_IO_STATIC_BIN_LEN);
1095 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
1097 readItems = pFile->Read(¤tFlag, 1);
1098 SysTryReturn(NID_IO, readItems == 1, r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Tell file has failed.");
1100 if (flag == FLAG_STATE_CVF)
1102 currentFlag = currentFlag | SECURE_IO_2_BYTES;
1103 currentFlag = currentFlag & SECURE_IO_HEX_FE;
1105 else if (flag == FLAG_STATE_CTF)
1107 currentFlag = currentFlag | 1;
1108 currentFlag = currentFlag & SECURE_IO_HEX_FD;
1110 else if (flag == FLAG_STATE_CVF_CTF)
1112 currentFlag = currentFlag | SECURE_IO_3_BYTES;
1114 else if (flag == FLAG_STATE_NONE)
1116 currentFlag = currentFlag & SECURE_IO_HEX_FC;
1120 return E_INVALID_STATE;
1123 r = pFile->Seek(FILESEEKPOSITION_BEGIN, SECURE_REG_HEADER_STRING_SIZE + SECURE_IO_STATIC_BIN_LEN);
1124 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
1126 r = pFile->Write(¤tFlag, 1);
1127 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to write data in file.", GetErrorMessage(r));
1129 r = pFile->Seek(FILESEEKPOSITION_BEGIN, current);
1130 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
1136 _SecureIoUtil::CheckRegistryFlag(byte* pHeader)
1139 byte flag = *(pHeader + SECURE_REG_HEADER_STRING_SIZE + SECURE_IO_STATIC_BIN_LEN);
1141 if (((flag | SECURE_IO_HEX_FD) == SECURE_IO_HEX_FF) && ((flag | SECURE_IO_HEX_FE) != SECURE_IO_HEX_FF))
1143 return FLAG_STATE_CVF;
1145 else if (((flag | SECURE_IO_HEX_FD) != SECURE_IO_HEX_FF) && ((flag | SECURE_IO_HEX_FE) == SECURE_IO_HEX_FF))
1147 return FLAG_STATE_CTF;
1149 else if ((flag | SECURE_IO_HEX_FC) == SECURE_IO_HEX_FF)
1151 return FLAG_STATE_CVF_CTF;
1155 return FLAG_STATE_NONE;
1160 _SecureIoUtil::MakeRegistryReplica(const String fileName, byte* pNameIndex)
1162 result r = E_SUCCESS;
1164 int nameIndex = *pNameIndex;
1169 SysTryReturn(NID_IO, nameIndex <= SECURE_IO_HEX_64, replicaName, E_INVALID_ARG, "[E_INVALID_ARG] Index number is too big.");
1173 replicaName = fileName + L".rpa ";
1174 if (!File::IsFileExist(replicaName))
1181 replicaName = fileName + L"_";
1182 replicaName.Append((int) nameIndex);
1183 replicaName.Append(L".rpa");
1185 if (!File::IsFileExist(replicaName))
1194 *pNameIndex = nameIndex;
1196 if (_FileImpl::IsFileExist(fileName))
1198 r = _FileImpl::Copy(fileName, replicaName, true);
1199 SysTryReturn(NID_IO, !IsFailed(r), replicaName, r, "[%s] Failed to copy file.", GetErrorMessage(r));
1203 // open registry replica file
1205 r = fileImpl.Construct(replicaName, "w", false, null);
1206 SysTryReturn(NID_IO, !IsFailed(r), replicaName, r, "[%s] Failed to create empty file.", GetErrorMessage(r));
1214 _SecureIoUtil::DeleteRegistryReplica(byte* pHeader, const String fileName)
1216 result r = E_SUCCESS;
1218 byte nameIndex = *(pHeader + SECURE_REG_HEADER_STRING_SIZE + SECURE_IO_9_BYTES);
1222 SysTryReturnResult(NID_IO, nameIndex <= SECURE_IO_HEX_64, E_INVALID_ARG, "Index number is too big.");
1226 replicaName = fileName + L".rpa ";
1230 replicaName = fileName + L"_";
1231 replicaName.Append((int) nameIndex);
1232 replicaName.Append(L".rpa");
1235 _FileImpl::Remove(replicaName);
1241 _SecureIoUtil::LoadRegistryReplica(byte** pHeader, int* pHeaderLen, const String fileName)
1243 result r = E_SUCCESS;
1246 char indexStr[MAX_BLOCK_INDEX_LEN];
1249 _FileImpl replicaFile;
1252 memset(indexStr, 0, MAX_BLOCK_INDEX_LEN);
1253 nameIndex = *(*pHeader + SECURE_REG_HEADER_STRING_SIZE + SECURE_IO_9_BYTES);
1259 SysTryReturnResult(NID_IO, nameIndex <= SECURE_IO_HEX_64, E_INVALID_ARG, "Index number is too big.");
1263 replicaName = fileName + L".rpa ";
1267 replicaName = fileName + L"_";
1268 replicaName.Append((int) nameIndex);
1269 replicaName.Append(L".rpa");
1272 if (Tizen::Io::_FileImpl::IsFileExist(replicaName))
1274 r = replicaFile.Construct(replicaName, "r", false, null);
1275 SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Constructing the file has failed.", GetErrorMessage(r));
1277 r = replicaFile.Seek(FILESEEKPOSITION_END, 0);
1278 SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Failed to seek in file.", GetErrorMessage(r));
1280 length = replicaFile.Tell();
1283 *pHeader = new (std::nothrow) byte[length];
1284 SysTryCatch(NID_IO, *pHeader != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
1285 *pHeaderLen = length;
1287 r = replicaFile.Seek(FILESEEKPOSITION_BEGIN, 0);
1288 SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Failed to seek in file.", GetErrorMessage(r));
1290 readItems = replicaFile.Read(*pHeader, length);
1291 SysTryCatch(NID_IO, readItems >= length, r = GetLastResult(), GetLastResult(), "[%s] Failed to read data from file.", GetErrorMessage(GetLastResult()));
1308 _SecureIoUtil::CheckSecureRegistryHeader(byte** pHeader, int* pHeaderLen, const String strFilePathPath, bool secureMode)
1310 result r = E_SUCCESS;
1314 _FlagState flag = FLAG_STATE_NONE;
1315 byte reservedValue[SECURE_IO_STATIC_BIN_LEN] = {0xCA, 0xFE, 0xBE, 0xBE, 0xDA, 0xEF, 0xEB, 0xEB};
1316 byte* pSecureRegistryHeader = *pHeader;
1319 //check if the registry is encrypted . (in normal and secure mode)
1320 ret = memcmp(pSecureRegistryHeader, SECURE_REG_HEADER_STRING, SECURE_REG_HEADER_STRING_SIZE);
1321 ret |= memcmp(pSecureRegistryHeader + SECURE_REG_HEADER_STRING_SIZE, reservedValue, SECURE_IO_STATIC_BIN_LEN);
1322 SysTryReturnResult(NID_IO, !(ret && secureMode == true), E_INVALID_ARG, "Failed to match secure header in file.");
1326 flag = CheckRegistryFlag(pSecureRegistryHeader);
1328 if (_FileImpl::IsFileExist(strFilePathPath) && !_SecureIoUtil::IsEmpty(strFilePathPath))
1330 r = fileImpl.Construct(strFilePathPath, "a+", false, null);
1331 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Constructing the file has failed.", GetErrorMessage(r));
1333 if (flag == FLAG_STATE_CVF_CTF)
1335 r = DeleteRegistryReplica(pSecureRegistryHeader, strFilePathPath);
1336 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to delete registry replica.", GetErrorMessage(r));
1338 r = SetRegistryFlag(&fileImpl, FLAG_STATE_CVF);
1339 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to set registry flags.", GetErrorMessage(r));
1342 else if (flag == FLAG_STATE_CTF)
1344 r = LoadRegistryReplica(pHeader, &readLen, strFilePathPath);
1345 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to load registry replica.", GetErrorMessage(r));
1347 SysTryReturn(NID_IO, *pHeader, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Failed to read secure registry file header.");
1349 pSecureRegistryHeader = *pHeader;
1350 *pHeaderLen = readLen;
1352 r = DeleteRegistryReplica(pSecureRegistryHeader, strFilePathPath);
1353 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to delete registry replica.", GetErrorMessage(r));
1355 r = SetRegistryFlag(&fileImpl, FLAG_STATE_CVF);
1356 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to set registry flags.", GetErrorMessage(r));
1358 else if (flag == FLAG_STATE_CVF)
1364 r = E_INVALID_STATE;
1373 _SecureIoUtil::CheckFlag(_NormalFile* pNormalFile, _FlagState* pFlag)
1375 result r = E_SUCCESS;
1380 r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, SECURE_FILE_HEADER_STRING_SIZE + SECURE_IO_STATIC_BIN_LEN);
1385 ret = pNormalFile->Read(&flag, SECURE_IO_FLAG_SIZE);
1389 r = GetLastResult();
1390 SysTryReturnResult(NID_IO, !(ret == 0 && r == E_END_OF_FILE), E_INVALID_ARG, "Failed to read secure file header.");
1392 r = GetLastResult();
1394 if (ret == 0 && IsEndOfFile(pNormalFile))
1399 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
1404 if (((flag | SECURE_IO_HEX_FD) == SECURE_IO_HEX_FF) && ((flag | SECURE_IO_HEX_FE) != SECURE_IO_HEX_FF))
1406 *pFlag = FLAG_STATE_CVF;
1408 else if (((flag | SECURE_IO_HEX_FD) != SECURE_IO_HEX_FF) && ((flag | SECURE_IO_HEX_FE) == SECURE_IO_HEX_FF))
1410 *pFlag = FLAG_STATE_CTF;
1412 else if ((flag | SECURE_IO_HEX_FC) == SECURE_IO_HEX_FF)
1414 *pFlag = FLAG_STATE_CVF_CTF;
1418 *pFlag = FLAG_STATE_NONE;
1425 _SecureIoUtil::SetFlag(_NormalFile* pNormalFile, _FlagState flag)
1427 result r = E_SUCCESS;
1430 byte currentFlag = 0;
1433 current = pNormalFile->Tell();
1436 r = GetLastResult();
1437 SysLog(NID_IO, "[%s] Failed to tell in file", GetErrorMessage(r));
1441 r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, SECURE_FILE_HEADER_STRING_SIZE + SECURE_IO_STATIC_BIN_LEN);
1442 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file", GetErrorMessage(r));
1444 readItems = pNormalFile->Read(¤tFlag, SECURE_IO_FLAG_SIZE);
1447 r = GetLastResult();
1449 if (readItems == 0 && IsEndOfFile(pNormalFile))
1454 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
1458 if (flag == FLAG_STATE_CVF)
1460 currentFlag = currentFlag | SECURE_IO_2_BYTES;
1461 currentFlag = currentFlag & SECURE_IO_HEX_FE;
1463 else if (flag == FLAG_STATE_CTF)
1465 currentFlag = currentFlag | 1;
1466 currentFlag = currentFlag & SECURE_IO_HEX_FD;
1468 else if (flag == FLAG_STATE_CVF_CTF)
1470 currentFlag = currentFlag | SECURE_IO_3_BYTES;
1472 else if (flag == FLAG_STATE_NONE)
1474 currentFlag = currentFlag & SECURE_IO_HEX_FC;
1478 SysAssert(false); // should not happen!
1480 r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, SECURE_FILE_HEADER_STRING_SIZE + SECURE_IO_STATIC_BIN_LEN);
1481 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file", GetErrorMessage(r));
1483 r = pNormalFile->Write(¤tFlag, SECURE_IO_FLAG_SIZE);
1484 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to write in file", GetErrorMessage(r));
1486 r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, current);
1487 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file", GetErrorMessage(r));
1493 _SecureIoUtil::DeleteBlockReplica(_NormalFile* pNormalFile, const String filePath)
1495 result r = E_SUCCESS;
1501 r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, SECURE_FILE_HEADER_STRING_SIZE + SECURE_IO_9_BYTES);
1502 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file", GetErrorMessage(r));
1504 readItems = pNormalFile->Read(&nameIndex, SECURE_IO_INDEX_SIZE);
1507 r = GetLastResult();
1509 if (readItems == 0 && IsEndOfFile(pNormalFile))
1514 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
1518 SysTryReturnResult(NID_IO, nameIndex <= SECURE_IO_HEX_64, E_INVALID_ARG, "Index number is too big.");
1522 replicaName = filePath + L".rpa ";
1526 replicaName = filePath + L"_";
1527 replicaName.Append((int) nameIndex);
1528 replicaName.Append(L".rpa");
1531 _FileImpl::Remove(replicaName);
1537 _SecureIoUtil::RestoreCorruptBlock(_NormalFile* pNormalFile, String fileName)
1539 result r = E_SUCCESS;
1540 String blockName = null;
1542 byte blockHeader[CIPHER_BLOCK_HEADER_SIZE] = {0, 0, 0};
1543 byte* pBlockDataCur = null;
1544 _NormalFile replicaFile;
1545 int startBlockNum = 0;
1551 r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, SECURE_FILE_HEADER_STRING_SIZE + SECURE_IO_9_BYTES);
1552 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file", GetErrorMessage(r));
1554 readItems = pNormalFile->Read(&nameIndex, SECURE_IO_INDEX_SIZE); // read index of temporary block name
1555 if (readItems < SECURE_IO_INDEX_SIZE)
1557 r = GetLastResult();
1559 if (readItems == 0 && IsEndOfFile(pNormalFile))
1564 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
1568 readItems = pNormalFile->Read(&dataLen, SECURE_IO_LOF_SIZE);
1569 if (readItems < SECURE_IO_LOF_SIZE)
1571 r = GetLastResult();
1573 if (readItems == 0 && IsEndOfFile(pNormalFile))
1578 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
1582 SysTryReturnResult(NID_IO, nameIndex < SECURE_IO_HEX_64, E_INVALID_ARG, "Index number is too big.");
1586 blockName = fileName + L".rpa ";
1590 blockName = fileName + L"_";
1591 blockName.Append((int) nameIndex);
1592 blockName.Append(L".rpa");
1595 if (_FileUtil::IsFileExist(blockName))
1597 r = replicaFile.Construct(blockName, "r");
1598 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to conctruct replica file.", GetErrorMessage(r));
1600 readItems = replicaFile.Read(blockHeader, CIPHER_BLOCK_HEADER_SIZE); //Read start block number (3bytes)
1601 if (readItems < CIPHER_BLOCK_HEADER_SIZE)
1603 r = GetLastResult();
1605 if (readItems == 0 && IsEndOfFile(pNormalFile))
1610 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
1614 pBlockDataCur = (byte*) (&startBlockNum);
1615 *pBlockDataCur = blockHeader[SECURE_IO_2_BYTES];
1616 *(pBlockDataCur + 1) = blockHeader[1];
1617 *(pBlockDataCur + SECURE_IO_2_BYTES) = blockHeader[0];
1619 r = replicaFile.Seek(FILESEEKPOSITION_END, 0);
1620 fileLength = replicaFile.Tell();
1621 SysTryReturn(NID_IO, fileLength != -1, GetLastResult(), GetLastResult(), "[%s] Failed to tell in file.", GetErrorMessage(GetLastResult()));
1623 r = replicaFile.Seek(FILESEEKPOSITION_BEGIN, CIPHER_BLOCK_HEADER_SIZE);
1624 unique_ptr< byte[] > pBlock(new (std::nothrow) byte[fileLength - CIPHER_BLOCK_HEADER_SIZE]);
1625 SysTryReturnResult(NID_IO, pBlock != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
1627 memset(pBlock.get(), 0, fileLength - CIPHER_BLOCK_HEADER_SIZE);
1629 readItems = replicaFile.Read(pBlock.get(), fileLength - CIPHER_BLOCK_HEADER_SIZE);
1630 if (readItems < (fileLength - CIPHER_BLOCK_HEADER_SIZE))
1632 r = GetLastResult();
1634 if (readItems == 0 && IsEndOfFile(pNormalFile))
1639 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
1643 r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, SECURE_FILE_HEADER_SIZE_V1 + (CIPHER_BLOCK_SIZE + CIPHER_BLOCK_HEADER_SIZE) * startBlockNum);
1645 r = pNormalFile->Write(pBlock.get(), fileLength - CIPHER_BLOCK_HEADER_SIZE);
1646 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to write in file.", GetErrorMessage(r));
1650 r = pNormalFile->Truncate(dataLen);
1651 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to truncate in file.", GetErrorMessage(r));
1657 _SecureIoUtil::MakeCipherBlockReplica(_NormalFile* pNormalFile, const String filePath, int dataPosition, int dataSize)
1659 result r = E_SUCCESS;
1660 int totalDataSize = 0;
1664 int startBlockNum = 0;
1666 long blockDataSize = 0;
1667 bool isEndOfBlock = false;
1669 byte* pBlockDataCur = null;
1670 byte blockHeader[CIPHER_BLOCK_HEADER_SIZE] = {0, 0, 0};
1672 _NormalFile tempBlockFile;
1674 totalDataSize = dataPosition + dataSize;
1677 headPos = pNormalFile->Tell();
1678 SysTryReturn(NID_IO, headPos != -1, GetLastResult(), GetLastResult(), "[%s] Failed to tell in file.", GetErrorMessage(GetLastResult()));
1680 ret = pNormalFile->Read(blockHeader, CIPHER_BLOCK_HEADER_SIZE);
1681 if (ret < CIPHER_BLOCK_HEADER_SIZE)
1683 r = GetLastResult();
1685 if (ret == 0 && IsEndOfFile(pNormalFile))
1690 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
1697 pBlockDataCur = (byte*) (&blockDataSize);
1698 *pBlockDataCur = blockHeader[SECURE_IO_2_BYTES];
1699 *(pBlockDataCur + 1) = blockHeader[1];
1700 *(pBlockDataCur + SECURE_IO_2_BYTES) = blockHeader[0];
1701 blockSize = blockSize + blockDataSize;
1703 if (blockSize >= totalDataSize)
1705 isEndOfBlock = true;
1708 if (blockDataSize % ONE_BLOCK_SIZE != 0)
1710 r = pNormalFile->Seek(FILESEEKPOSITION_CURRENT, blockDataSize + ONE_BLOCK_SIZE - blockDataSize % ONE_BLOCK_SIZE);
1714 r = pNormalFile->Seek(FILESEEKPOSITION_CURRENT, blockDataSize);
1717 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
1724 if (IsEndOfFile(pNormalFile))
1729 ret = pNormalFile->Read(blockHeader, CIPHER_BLOCK_HEADER_SIZE);
1730 if (ret < CIPHER_BLOCK_HEADER_SIZE)
1732 r = GetLastResult();
1734 if (ret == 0 && IsEndOfFile(pNormalFile))
1739 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
1745 tailPos = pNormalFile->Tell();
1746 SysTryReturn(NID_IO, tailPos != -1, GetLastResult(), GetLastResult(), "[%s] Failed to tell in file.", GetErrorMessage(GetLastResult()));
1748 startBlockNum = (headPos - SECURE_FILE_HEADER_SIZE_V1) / (CIPHER_BLOCK_SIZE + CIPHER_BLOCK_HEADER_SIZE);
1750 r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, headPos);
1751 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
1753 unique_ptr< byte[] > pBlockReplica(new (std::nothrow) byte[tailPos - headPos + CIPHER_BLOCK_HEADER_SIZE]);
1754 SysTryReturnResult(NID_IO, pBlockReplica != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
1756 *(reinterpret_cast< byte* >(pBlockReplica.get()) + SECURE_IO_2_BYTES) = (byte) (startBlockNum & SECURE_IO_HEX_FF);
1757 *(reinterpret_cast< byte* >(pBlockReplica.get()) + 1) = (byte) ((startBlockNum >> SECURE_IO_8_BITS) & SECURE_IO_HEX_FF);
1758 *(reinterpret_cast< byte* >(pBlockReplica.get())) = (byte) ((startBlockNum >> (SECURE_IO_8_BITS * SECURE_IO_2_BYTES)) & SECURE_IO_HEX_FF);
1760 ret = pNormalFile->Read(reinterpret_cast< byte* >(pBlockReplica.get()) + CIPHER_BLOCK_HEADER_SIZE, tailPos - headPos);
1761 if (ret < (tailPos - headPos))
1763 r = GetLastResult();
1765 if (ret == 0 && IsEndOfFile(pNormalFile))
1770 SysLog(NID_IO, "[%s] Failed to read data from file.", GetErrorMessage(r));
1776 SysTryReturnResult(NID_IO, nameIndex <= SECURE_IO_HEX_64, E_INVALID_ARG, "Index number is too big.");
1780 replicaName = filePath + L".rpa ";
1781 if (!File::IsFileExist(replicaName))
1788 replicaName = filePath + L"_";
1789 replicaName.Append((int) nameIndex);
1790 replicaName.Append(L".rpa");
1792 if (!File::IsFileExist(replicaName))
1800 r = tempBlockFile.Construct(replicaName, "w");
1801 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to call construct.", GetErrorMessage(r));
1803 r = tempBlockFile.Write(pBlockReplica.get(), tailPos - headPos + CIPHER_BLOCK_HEADER_SIZE);
1804 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to write in file.", GetErrorMessage(r));
1806 r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, 25);
1807 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
1809 r = pNormalFile->Write(&nameIndex, 1);
1810 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to write in file.", GetErrorMessage(r));
1812 r = pNormalFile->Seek(FILESEEKPOSITION_BEGIN, headPos);
1813 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
1819 _SecureIoUtil::IsNormalDatabase(_DatabaseMode mode)
1822 if (mode == DATABASE_MODE_NORMAL)
1830 _SecureIoUtil::IsSecureDatabase(_DatabaseMode mode)
1833 if (mode == DATABASE_MODE_SECURE)
1841 _SecureIoUtil::GetDatabaseMode(char* pStrPhysicalDbPath)
1843 result r = E_SUCCESS;
1845 unsigned long readBytes = 0;
1846 char buffer[SQLITE_HEADER_SIZE] = {0, };
1847 char magicNum1[SECURE_IO_MAGIC_NUMBER_SIZE] = {0xCA, 0xFE, 0xBE, 0xBE};
1848 char magicNum2[SECURE_IO_MAGIC_NUMBER_SIZE] = {0xDA, 0xEF, 0xEF, 0xEB};
1849 _NormalFile normalFile;
1853 r = normalFile.Construct(pStrPhysicalDbPath, "r");
1854 SysTryReturn(NID_IO, !IsFailed(r), DATABASE_MODE_ERROR, r, "[%s] Failed to open file (%s) in read mode", GetErrorMessage(r), pStrPhysicalDbPath);
1856 r = normalFile.Seek(FILESEEKPOSITION_END, 0);
1857 SysTryReturn(NID_IO, !IsFailed(r), DATABASE_MODE_ERROR, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
1859 fileLength = normalFile.Tell();
1860 if (fileLength <= 0)
1862 return DATABASE_MODE_NONE;
1865 r = normalFile.Seek(FILESEEKPOSITION_BEGIN, 0);
1866 SysTryReturn(NID_IO, !IsFailed(r), DATABASE_MODE_ERROR, r, "[%s] Failed to seek in file.", GetErrorMessage(r));
1868 readBytes = normalFile.Read(buffer, SQLITE_HEADER_SIZE);
1869 r = GetLastResult();
1870 SysTryReturn(NID_IO, readBytes > 0, DATABASE_MODE_ERROR, r, "[%s] File is not opened for reading or else failed to read data from file.", GetErrorMessage(r));
1872 if (!strncmp(buffer, "SQLite format 3", SQLITE_FORMAT_STR_SIZE))
1874 return DATABASE_MODE_NORMAL;
1876 else if (!memcmp((void*) buffer, magicNum1, SECURE_IO_MAGIC_NUMBER_SIZE) && !memcmp((void*) (buffer + SECURE_IO_12_BYTES), magicNum2, SECURE_IO_MAGIC_NUMBER_SIZE))
1878 return DATABASE_MODE_SECURE;
1881 return DATABASE_MODE_ERROR;
1885 _SecureIoUtil::GenerateDatabaseKeyN(const Tizen::Base::ByteBuffer* pUserKey)
1890 byte* pDbKey = null;
1894 unique_ptr< ByteBuffer > pKeyBuffer(GetSecureKeyN(pUserKey));
1896 SysTryReturn(NID_IO, pKeyBuffer != null, null, E_INVALID_ARG, "[E_INVALID_ARG] Failed to generate secure key.");
1898 pKey = const_cast< byte* >(pKeyBuffer->GetPointer());
1900 pDbKey = new (std::nothrow) byte[DATABASE_KEY_LENGTH * SECURE_IO_2_BYTES + 1];
1901 SysTryReturn(NID_IO, pDbKey != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
1903 memset(pDbKey, 0, DATABASE_KEY_LENGTH * SECURE_IO_2_BYTES + 1);
1905 for (int i = 0; i < DATABASE_KEY_LENGTH; i++)
1907 lowByte = pKey[i] & SECURE_IO_HEX_0F;
1908 highByte = (pKey[i] >> SECURE_IO_4_BITS) & SECURE_IO_HEX_0F;
1909 if (lowByte <= SECURE_IO_9_BYTES)
1911 pDbKey[i * SECURE_IO_2_BYTES + 1] = lowByte + '0';
1915 pDbKey[i * SECURE_IO_2_BYTES + 1] = lowByte - SECURE_IO_10_BYTES + 'A';
1918 if (highByte <= SECURE_IO_9_BYTES)
1920 pDbKey[i * SECURE_IO_2_BYTES] = highByte + '0';
1924 pDbKey[i * SECURE_IO_2_BYTES] = highByte - SECURE_IO_10_BYTES + 'A';
1932 _SecureIoUtil::IsEmpty(const String& filePath)
1934 result r = E_SUCCESS;
1935 FileAttributes attribute;
1938 r = File::GetAttributes(filePath, attribute);
1945 if (attribute.GetFileSize() == 0)