2 * Copyright (c) 2000-2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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.
17 #include "TADC_Core.h"
18 #include "TADC_ErrorCode.h"
19 #include "DTapps2Rights.h"
20 #include "DrmFileHandler.h"
26 #define TDC_DECRYPT_BLOCKSIZE 512
28 DrmFileHandler::DrmFileHandler(void)
36 DrmFileHandler::~DrmFileHandler(void)
38 if (m_pFilePath != NULL)
53 if (m_pDecBuf != NULL)
64 int DrmFileHandler::Construct(const char* szDrmFilePath)
66 T_FILE_HEADER t_FileHeader;
67 T_DRM_HEADER t_DRMHeader;
70 int ret = TADC_SUCCESS;
73 // 1. Check the file is TADC DRM file.
74 memset(&t_FileHeader, 0x00, sizeof(t_FileHeader));
75 memset(&t_DRMHeader, 0x00, sizeof(T_DRM_HEADER));
76 memset(&t_RO, 0x00, sizeof(T_RO));
78 DRM_TAPPS_LOG("%s starts", __func__);
80 if (szDrmFilePath == NULL)
82 DRM_TAPPS_EXCEPTION("Parameters NULL!");
83 ret = TADC_PARAMETER_ERROR;
88 ret = TADC_GetDRMHeaderFromFile(szDrmFilePath, &t_FileHeader, &t_DRMHeader);
92 DRM_TAPPS_EXCEPTION("Error : TADC_GetDRMHeaderFromFile() - %s TADC Error Code - %d", szDrmFilePath, ret);
93 ret = TADC_NOTTADCFILE_ERROR;
98 // 2. Validate license and get the CEK for the DRM file
99 bRet = DTappsGetCEK((char*)t_DRMHeader.CID, &t_RO);
102 DRM_TAPPS_EXCEPTION("Error : DTappsGetCEK() - %s", t_DRMHeader.CID);
103 ret = TADC_GET_CEK_ERROR;
108 // 3. Setting the member variable
109 m_pFilePath = new unsigned char[strlen(szDrmFilePath) + 1];
110 memset(m_pFilePath, 0x00, strlen(szDrmFilePath) + 1);
111 memcpy(m_pFilePath, szDrmFilePath, strlen(szDrmFilePath));
113 m_pCID = new unsigned char[strlen((char*)t_DRMHeader.CID) + 1];
114 memset(m_pCID, 0x00, strlen((char*)t_DRMHeader.CID) + 1);
115 memcpy(m_pCID, t_DRMHeader.CID, strlen((char*)t_DRMHeader.CID));
117 m_pCEK = new unsigned char[CEK_SIZE + 1];
118 memset(m_pCEK, 0x00, CEK_SIZE + 1);
119 memcpy(m_pCEK, t_RO.t_Content.CEK, CEK_SIZE);
121 m_encryptionLevel = t_DRMHeader.EncryptionLevel;
122 m_encryptionRange = t_DRMHeader.EncryptionRange;
123 m_plaintextSize = t_DRMHeader.PlaintextSize;
125 // 4. Open the DRM file and set the filepointer to member variable
126 m_pFP = fopen(szDrmFilePath, "rb");
129 DRM_TAPPS_EXCEPTION("Error : fopen() - %s", szDrmFilePath);
130 ret = TADC_FILE_OPEN_ERROR;
135 m_PlaintextStartOffset = t_FileHeader.Offset1 + 35 + t_DRMHeader.XmlSize;
137 fseek(m_pFP, 0, SEEK_END);
138 m_OriginEndOffset = ftell(m_pFP);
140 m_plaintextSize = m_OriginEndOffset - m_PlaintextStartOffset;
141 if (m_plaintextSize != t_DRMHeader.PlaintextSize)
143 DRM_TAPPS_EXCEPTION("Error : plaintext file size incorrect. real = %ld, header = %ld", m_plaintextSize, t_DRMHeader.PlaintextSize);
144 ret = TADC_FILE_OPEN_ERROR;
149 m_DrmEndOffset = m_plaintextSize;
151 fseek(m_pFP, m_PlaintextStartOffset, SEEK_SET);
152 m_OriginCurOffset = ftell(m_pFP);
155 m_blockCnt = (m_plaintextSize / 512) + ((m_plaintextSize % 512) ? 1 : 0);
160 DRM_TAPPS_LOG("m_pCEK = %s", m_pCEK);
161 DRM_TAPPS_LOG("m_pCID = %s", m_pCID);
162 DRM_TAPPS_LOG("m_pFilePath = %s", m_pFilePath);
164 DRM_TAPPS_LOG("m_encryptionLevel = %ld", m_encryptionLevel);
165 DRM_TAPPS_LOG("m_encryptionRange = %ld", m_encryptionRange);
166 DRM_TAPPS_LOG("m_plaintextSize = %ld", m_plaintextSize);
168 DRM_TAPPS_LOG("m_PlaintextStartOffset = %ld", m_PlaintextStartOffset);
169 DRM_TAPPS_LOG("m_OriginEndOffset = %ld", m_OriginEndOffset);
171 DRM_TAPPS_LOG("m_OriginCurOffset = %ld", m_OriginCurOffset);
172 DRM_TAPPS_LOG("m_DrmCurOffset = %ld", m_DrmCurOffset);
173 DRM_TAPPS_LOG("m_DrmEndOffset = %ld", m_DrmEndOffset);
175 DRM_TAPPS_LOG("m_blockCnt = %ld", m_blockCnt);
176 DRM_TAPPS_LOG("m_curBlockIndex = %ld", m_curBlockIndex);
183 TADC_MEMFree_FileHeader(&t_FileHeader);
184 TADC_MEMFree_DRMHeader(&t_DRMHeader);
185 TADC_MEMFree_RO(&t_RO);
190 int DrmFileHandler::DrmSeek(long long offset, int origin)
192 int nRet = TADC_SUCCESS;
193 long long OriginOffset = 0;
194 long long DrmOffset = 0;
199 if (origin == SEEK_SET)
202 if (DrmOffset < 0 || DrmOffset > m_plaintextSize)
204 DRM_TAPPS_EXCEPTION("Parameter Wrong! Offset can not be minus. offset=%lld, m_OriginCurOffset=%lld, m_plaintextSize=%lld", offset, m_OriginCurOffset, m_plaintextSize);
205 return TADC_PARAMETER_ERROR;
208 OriginOffset = m_PlaintextStartOffset + DrmOffset;
209 if (fseek(m_pFP, OriginOffset, SEEK_SET) != 0)
211 DRM_TAPPS_EXCEPTION("fseek failed.");
212 return TADC_FILE_READ_ERROR;
215 m_OriginCurOffset = OriginOffset;
216 m_DrmCurOffset = DrmOffset;
218 else if (origin == SEEK_CUR)
220 temp = m_OriginCurOffset;
224 DRM_TAPPS_EXCEPTION("GetOriginCurOffset() failed.");
225 return TADC_FILE_READ_ERROR;
228 OriginOffset = temp + offset;
229 DrmOffset = OriginOffset - m_PlaintextStartOffset;
231 if (DrmOffset < 0 || DrmOffset > m_plaintextSize)
233 DRM_TAPPS_EXCEPTION("Parameter Wrong! Offset can not be minus. offset=%lld, m_OriginCurOffset=%lld, OriginOffset=%lld, DrmOffset=%lld, m_plaintextSize=%lld", offset, temp, OriginOffset, DrmOffset, m_plaintextSize);
234 return TADC_PARAMETER_ERROR;
237 if (fseek(m_pFP, OriginOffset, SEEK_SET) != 0)
239 DRM_TAPPS_EXCEPTION("fseek failed.");
240 return TADC_FILE_READ_ERROR;
243 m_OriginCurOffset = OriginOffset;
244 m_DrmCurOffset = DrmOffset;
246 else if (origin == SEEK_END)
248 OriginOffset = m_OriginEndOffset + offset;
249 if (fseek(m_pFP, OriginOffset, SEEK_SET) != 0)
251 DRM_TAPPS_EXCEPTION("fseek failed.");
252 return TADC_FILE_READ_ERROR;
255 DrmOffset = OriginOffset - m_PlaintextStartOffset;
256 if (DrmOffset < 0 || DrmOffset > m_plaintextSize)
258 DRM_TAPPS_EXCEPTION("Parameter Wrong! Offset can not be minus. offset=%lld, m_OriginCurOffset=%lld, OriginOffset=%lld, DrmOffset=%lld, m_plaintextSize=%lld", offset, temp, OriginOffset, DrmOffset, m_plaintextSize);
259 return TADC_PARAMETER_ERROR;
262 m_OriginCurOffset = OriginOffset;
263 m_DrmCurOffset = DrmOffset;
267 DRM_TAPPS_EXCEPTION("Parameter Wrong!");
268 return TADC_PARAMETER_ERROR;
274 long long DrmFileHandler::DrmTell(void)
276 return m_DrmCurOffset;
277 // return GetDrmCurOffset();
280 int DrmFileHandler::DrmDecryptBlocks(void)
284 int ret = TADC_SUCCESS;
285 const char* packagePath = (const char*)m_pFilePath;
286 long long EncBlockCnt = 0;
287 T_FILE_HEADER t_FileHeader;
288 T_DRM_HEADER t_DRMHeader;
289 T_DEVICE_INFO t_DeviceInfo;
291 DrmTdcFileHeader fileHeader;
297 // 1. Check the file is TADC DRM file.
298 memset(&t_FileHeader, 0x00, sizeof(t_FileHeader));
299 memset(&t_DRMHeader, 0x00, sizeof(T_DRM_HEADER));
300 memset(&t_DeviceInfo, 0x00, sizeof(T_DEVICE_INFO));
301 memset(&t_RO, 0x00, sizeof(T_RO));
303 bRet = DrmTdcGetFileHeader(packagePath, &fileHeader);
306 DRM_TAPPS_EXCEPTION("DrmDecryptBlocks Error : DrmTdcGetFileHeader()");
307 ret = TADC_GET_FILEHEADER_ERROR;
312 bRet = DTappsGetCEK(fileHeader.cid, &t_RO);
315 DRM_TAPPS_SECURE_EXCEPTION("DrmDecryptBlocks Error : DTappsGetCEK() packagePath=%s, fileHeader.cid=%s", packagePath, fileHeader.cid);
316 ret = TADC_GET_CEK_ERROR;
320 DRM_TAPPS_SECURE_LOG("fileHeader.cid=%s, t_RO.t_Content.CEK=%s", fileHeader.cid, t_RO.t_Content.CEK);
322 if ((ret = TADC_SetDeviceInfo(&t_DeviceInfo) ) == TADC_GETDUID_ERROR)
324 DRM_TAPPS_EXCEPTION("DrmDecryptBlocks Error : TADC_SetDeviceInfo(), TADC Error Code - %d", ret);
325 ret = TADC_FILE_READ_ERROR;
330 ret = TADC_GetDRMHeaderFromFile(packagePath, &t_FileHeader, &t_DRMHeader);
333 DRM_TAPPS_EXCEPTION("DrmDecryptBlocks Error : TADC_GetDRMHeaderFromFile() - %s, TADC Error Code - %d", packagePath, ret);
334 ret = TADC_NOTTADCFILE_ERROR;
340 if ((ret = TADC_GetCEK(&t_DeviceInfo, &t_RO, &t_DRMHeader )) < 0)
342 DRM_TAPPS_EXCEPTION("DrmDecryptBlocks Error: TADC_GetCEK, TADC Error Code - %d", ret);
343 ret = TADC_GET_CEK_ERROR;
348 if (fseek(m_pFP, m_PlaintextStartOffset, SEEK_SET ) != 0)
350 DRM_TAPPS_EXCEPTION("DrmDecryptBlocks Error :fseek failed.");
351 ret = TADC_FILE_READ_ERROR;
356 if (m_encryptionRange == -1)
358 EncBlockCnt = m_blockCnt;
362 EncBlockCnt = m_encryptionRange;
365 m_pDecBuf = new unsigned char[(EncBlockCnt * TDC_DECRYPT_BLOCKSIZE) + 1];
366 if (m_pDecBuf == NULL)
368 DRM_TAPPS_EXCEPTION("DrmRead Error : m_pDecBuf Memory allocation failed");
369 return TADC_MEMAlOC_ERROR;
372 ReadLen = fread(m_pDecBuf, 1, EncBlockCnt * TDC_DECRYPT_BLOCKSIZE, m_pFP);
374 for (k = 0 ; k < ReadLen ; k += 512)
378 DecLen = ReadLen - k;
379 DecLen = ( DecLen > 512) ? 512 : DecLen;
381 if ((ret = TADC_DecryptBlock((char*)m_pDecBuf + k, DecLen, &t_DRMHeader)) < 0)
383 DRM_TAPPS_EXCEPTION("DrmDecryptBlocks Error : TADC_DecryptBlock, TADC Error Code - %d", ret);
384 ret = TADC_DECRYPT_PACKAGE_ERROR;
392 TADC_MEMFree_FileHeader(&t_FileHeader);
393 TADC_MEMFree_DRMHeader(&t_DRMHeader);
394 TADC_MEMFree_RO(&t_RO);
398 int DrmFileHandler::DrmRead(void* pBuf, long long buflen, long long* pReadLen)
400 unsigned char *pNewReadBuf = NULL;
401 unsigned char *pTempReadBuf = NULL;
402 int ret = TADC_SUCCESS;
405 long long EncBlockCnt = 0;
407 if (m_encryptionRange == -1)
409 EncBlockCnt = m_blockCnt;
413 EncBlockCnt = m_encryptionRange;
416 if (m_DrmCurOffset > EncBlockCnt * TDC_DECRYPT_BLOCKSIZE)
418 pNewReadBuf = (TADC_U8*)TADC_IF_Malloc(buflen + 1);
419 if (pNewReadBuf == NULL)
421 DRM_TAPPS_EXCEPTION("DrmRead Error : pNewReadBuf Malloc Fail");
422 return TADC_MEMAlOC_ERROR;
425 ReadLen = fread(pNewReadBuf, 1, buflen, m_pFP);
427 TADC_IF_MemCpy(pBuf , pNewReadBuf , ReadLen);
428 TADC_IF_Free(pNewReadBuf);
434 if (buflen > EncBlockCnt * TDC_DECRYPT_BLOCKSIZE - m_DrmCurOffset)
436 pTempReadBuf = (TADC_U8*)TADC_IF_Malloc((buflen) + 1);
437 if (pTempReadBuf == NULL)
439 DRM_TAPPS_EXCEPTION("DrmRead Error : pTempReadBuf Malloc Fail");
440 ret = TADC_MEMAlOC_ERROR;
445 m_decReadlen = (EncBlockCnt * TDC_DECRYPT_BLOCKSIZE) - m_DrmCurOffset;
446 TADC_IF_MemCpy(pTempReadBuf , (char*)m_pDecBuf + m_DrmCurOffset , m_decReadlen);
448 m_extraReadlen = buflen - m_decReadlen;
450 if (fseek(m_pFP, m_decReadlen, SEEK_CUR) != 0)
452 DRM_TAPPS_EXCEPTION("DrmRead Error: fseek failed.");
453 ret = TADC_FILE_READ_ERROR;
458 pNewReadBuf = (TADC_U8*)TADC_IF_Malloc(m_extraReadlen + 1);
459 if (pNewReadBuf == NULL)
461 DRM_TAPPS_EXCEPTION("DrmRead Error : pNewReadBuf Malloc Fail");
462 ret = TADC_MEMAlOC_ERROR;
466 ReadLen = fread(pNewReadBuf, 1, m_extraReadlen, m_pFP);
468 TADC_IF_MemCpy((char*)pTempReadBuf + m_decReadlen, pNewReadBuf , ReadLen);
469 TADC_IF_MemCpy(pBuf , pTempReadBuf , buflen);
471 TADC_IF_Free(pNewReadBuf);
472 TADC_IF_Free(pTempReadBuf);
476 if (m_DrmCurOffset == 0)
478 TADC_IF_MemCpy(pBuf, (char*)m_pDecBuf + m_decReadlen , buflen);
482 TADC_IF_MemCpy(pBuf, (char*)m_pDecBuf + m_DrmCurOffset + m_decReadlen, buflen);
484 m_decReadlen = m_decReadlen + buflen;
493 TADC_IF_Free(pNewReadBuf);
494 TADC_IF_Free(pTempReadBuf);
498 long long DrmFileHandler::GetCurBlockIndex(void)
500 m_curBlockIndex = (m_DrmCurOffset / 512) + ((m_DrmCurOffset % 512) ? 1 : 0);
502 return m_curBlockIndex;