33 #include <sys/utsname.h>
36 #define NYI_KEYSYSTEM "keysystem-placeholder"
39 extern DRM_CONST_STRING g_dstrDrmPath;
44 const DRM_WCHAR g_rgwchCDMDrmStoreName[] =
45 { WCHAR_CAST(
'/'), WCHAR_CAST(
'o'), WCHAR_CAST(
'p'), WCHAR_CAST(
't'),
46 WCHAR_CAST(
'/'), WCHAR_CAST(
'd'), WCHAR_CAST(
'r'), WCHAR_CAST(
'm'),
47 WCHAR_CAST(
'/'), WCHAR_CAST(
'p'), WCHAR_CAST(
'l'), WCHAR_CAST(
'a'),
48 WCHAR_CAST(
'y'), WCHAR_CAST(
'r'), WCHAR_CAST(
'e'), WCHAR_CAST(
'a'),
49 WCHAR_CAST(
'd'), WCHAR_CAST(
'y'), WCHAR_CAST(
'/'), WCHAR_CAST(
'd'),
50 WCHAR_CAST(
'r'), WCHAR_CAST(
'm'), WCHAR_CAST(
's'), WCHAR_CAST(
't'),
51 WCHAR_CAST(
'o'), WCHAR_CAST(
'r'), WCHAR_CAST(
'e'), WCHAR_CAST(
'.'),
52 WCHAR_CAST(
'd'), WCHAR_CAST(
'a'), WCHAR_CAST(
't'), WCHAR_CAST(
'\0') };
55 const DRM_WCHAR g_rgwchCDMDrmPath[] =
56 { WCHAR_CAST(
'/'), WCHAR_CAST(
'o'), WCHAR_CAST(
'p'), WCHAR_CAST(
't'),
57 WCHAR_CAST(
'/'), WCHAR_CAST(
'd'), WCHAR_CAST(
'r'), WCHAR_CAST(
'm'),
58 WCHAR_CAST(
'/'), WCHAR_CAST(
'p'), WCHAR_CAST(
'l'), WCHAR_CAST(
'a'),
59 WCHAR_CAST(
'y'), WCHAR_CAST(
'r'), WCHAR_CAST(
'e'), WCHAR_CAST(
'a'),
60 WCHAR_CAST(
'd'), WCHAR_CAST(
'y'), WCHAR_CAST(
'\0') };
62 const DRM_CONST_STRING g_dstChainTitle = CREATE_DRM_STRING(
63 g_rgwchCDMDrmStoreName);
64 const DRM_CONST_STRING g_dstrCDMDrmPath = CREATE_DRM_STRING(g_rgwchCDMDrmPath);
65 const DRM_CONST_STRING *g_rgpdstrRights[1] =
66 { &g_dstrWMDRM_RIGHT_PLAYBACK };
82 const DRM_BYTE *pbData,
const DRM_DWORD cbData, DRM_DWORD ibGuidOffset,
85 DRM_RESULT drm_res = DRM_SUCCESS;
86 DRM_DWORD dwResult = 0;
88 ChkArg(pbData != NULL);
89 ChkArg(pDrmGuid != NULL);
90 ChkOverflow(cbData, ibGuidOffset);
91 ChkDR(DRM_DWordSub(cbData, ibGuidOffset, &dwResult));
92 ChkBOOL(dwResult >= DRM_GUID_LEN, DRM_E_BUFFERTOOSMALL);
95 NETWORKBYTES_TO_DWORD(pDrmGuid->Data1, pbData, ibGuidOffset);
96 ChkDR(DRM_DWordAdd(ibGuidOffset, SIZEOF(DRM_DWORD), &ibGuidOffset));
98 NETWORKBYTES_TO_WORD(pDrmGuid->Data2, pbData, ibGuidOffset);
99 ChkDR(DRM_DWordAdd(ibGuidOffset, SIZEOF(DRM_WORD), &ibGuidOffset));
101 NETWORKBYTES_TO_WORD(pDrmGuid->Data3, pbData, ibGuidOffset);
102 ChkDR(DRM_DWordAdd(ibGuidOffset, SIZEOF(DRM_WORD), &ibGuidOffset));
105 DRM_BYT_CopyBytes(pDrmGuid->Data4, 0, pbData, ibGuidOffset, 8);
107 ErrorExit:
return drm_res;
114 AampDrmSession(logObj, PLAYREADY_KEY_SYSTEM_STRING), m_ptrAppContext(NULL), m_sbOpaBuf(NULL),
115 m_cbOpaBuf(0), m_sbRevocateBuf(NULL), m_eKeyState(
KEY_INIT), m_fCommit(FALSE),
116 m_pbChallenge(NULL), m_cbChallenge(0), m_ptrDestURL(NULL), m_pbPRO(NULL), m_cbPRO(0)
118 pthread_mutex_init(&decryptMutex,NULL);
132 DRM_RESULT drm_res = DRM_SUCCESS;
133 DRM_ID aampSessionId;
134 DRM_DWORD cchEncSesID = SIZEOF(m_rgchSesnID);
136 char *envParseInitData = NULL;
139 m_sbOpaBuf = (DRM_BYTE *) Oem_MemAlloc(
140 MINIMUM_APPCONTEXT_OPAQUE_BUFFER_SIZE));
141 m_cbOpaBuf = MINIMUM_APPCONTEXT_OPAQUE_BUFFER_SIZE;
144 m_ptrAppContext = (DRM_APP_CONTEXT *) Oem_MemAlloc(
145 SIZEOF(DRM_APP_CONTEXT)));
147 g_dstrDrmPath = g_dstrCDMDrmPath;
154 static pthread_mutex_t sessionMutex = PTHREAD_MUTEX_INITIALIZER;
155 pthread_mutex_lock(&sessionMutex);
156 drm_res = Drm_Initialize(m_ptrAppContext,
157 NULL, m_sbOpaBuf, m_cbOpaBuf, &g_dstChainTitle);
158 pthread_mutex_unlock(&sessionMutex);
161 AAMPLOG_WARN(
"Printing initialization result : %08x ", drm_res);
166 if (DRM_REVOCATION_IsRevocationSupported())
169 m_sbRevocateBuf = (DRM_BYTE *) Oem_MemAlloc(
170 REVOCATION_BUFFER_SIZE));
173 Drm_Revocation_SetBuffer(m_ptrAppContext, m_sbRevocateBuf,
174 REVOCATION_BUFFER_SIZE));
179 Oem_Random_GetBytes(NULL, (DRM_BYTE *) &aampSessionId,
180 SIZEOF(aampSessionId)));
182 ZEROMEM(m_rgchSesnID, SIZEOF(m_rgchSesnID));
185 DRM_B64_EncodeA((DRM_BYTE *) &aampSessionId, SIZEOF(aampSessionId),
186 m_rgchSesnID, &cchEncSesID, 0));
188 AAMPLOG_WARN(
"initAampDRMSession :: Playready initialized with session id : %s",m_rgchSesnID);
190 ChkBOOL(m_eKeyState ==
KEY_INIT, DRM_E_INVALIDARG);
193 AAMPLOG_ERR(
"Playready initialization failed code : %08x ", drm_res);
202 uint32_t f_cbInitData, std::string &customData)
204 DRM_RESULT drm_res = DRM_SUCCESS;
206 if (f_pbInitData != NULL)
209 cout <<
"parseinitdata..." << endl;
220 AAMPLOG_WARN(
"PRO found in initdata!");
224 drm_res = Drm_Content_SetProperty(m_ptrAppContext, DRM_CSP_AUTODETECT_HEADER,
230 AAMPLOG_WARN(
"PRO not found in initdata!");
232 drm_res = Drm_Content_SetProperty(m_ptrAppContext, DRM_CSP_AUTODETECT_HEADER,
233 f_pbInitData, f_cbInitData);
237 AAMPLOG_TRACE(
"initAampDRMSession :: Printing SetProperty result : %08x ", drm_res);
243 ChkBOOL(m_eKeyState ==
KEY_INIT, DRM_E_INVALIDARG);
247 AAMPLOG_ERR(
"Playready init data binding failed : Error code : %08x ",drm_res);
257 pthread_mutex_destroy(&decryptMutex);
258 SAFE_OEM_FREE(m_pbChallenge);
259 SAFE_OEM_FREE(m_ptrDestURL);
262 SAFE_OEM_FREE(m_pbPRO);
265 if (DRM_REVOCATION_IsRevocationSupported())
266 SAFE_OEM_FREE(m_sbRevocateBuf);
268 SAFE_OEM_FREE(m_sbOpaBuf);
269 SAFE_OEM_FREE(m_ptrAppContext);
272 if(m_pOutputProtection)
274 m_pOutputProtection->Release();
279 static DRM_ID CLSID_PlayReadyProtectionSystemID =
280 { 0x79, 0xf0, 0x04, 0x9a, 0x40, 0x98, 0x86, 0x42, 0xab, 0x92, 0xe6, 0x5b, 0xe0,
284 static DRM_ID PSSH_BOX_GUID =
285 { 0x18, 0x4f, 0x8a, 0xd0, 0xf3, 0x10, 0x82, 0x4a, 0xb6, 0xc8, 0x32, 0xd8, 0xab,
293 DRM_DWORD f_cbInitData, DRM_DWORD *f_pibPRO, DRM_DWORD *f_pcbPRO)
295 DRM_RESULT drm_res = DRM_SUCCESS;
297 DRM_DWORD cbSize = 0;
298 DRM_DWORD dwType = 0;
299 DRM_WORD wVersion = 0;
301 DRM_GUID guidSystemID = EMPTY_DRM_GUID;
302 DRM_GUID guidUUID = EMPTY_DRM_GUID;
303 DRM_DWORD cbSystemSize = 0;
304 DRM_BOOL fFound = FALSE;
305 DRM_BOOL fUUIDBox = FALSE;
306 DRM_DWORD cbMultiKid = 0;
307 DRM_DWORD dwResult = 0;
309 ChkArg(f_pbInitData != NULL);
310 ChkArg(f_cbInitData > 0);
311 ChkArg(f_pibPRO != NULL);
312 ChkArg(f_pcbPRO != NULL);
317 while (ibCur < f_cbInitData && !fFound)
319 ChkDR(DRM_DWordAdd(ibCur, SIZEOF(DRM_DWORD), &dwResult));
320 ChkBufferSize(dwResult, f_cbInitData);
321 NETWORKBYTES_TO_DWORD(cbSize, f_pbInitData, ibCur);
324 ChkDR(DRM_DWordAdd(ibCur, SIZEOF(DRM_DWORD), &dwResult));
325 ChkBufferSize(dwResult, f_cbInitData);
326 NETWORKBYTES_TO_DWORD(dwType, f_pbInitData, ibCur);
330 if (dwType == 0x75756964)
332 ChkDR(DRM_DWordAdd(ibCur, SIZEOF(DRM_GUID), &dwResult));
333 ChkBufferSize(dwResult, f_cbInitData);
337 f_cbInitData, ibCur, &guidUUID));
340 ChkBOOL(MEMCMP(&guidUUID, &PSSH_BOX_GUID, SIZEOF(DRM_ID)) == 0,
346 ChkBOOL(dwType == 0x70737368, DRM_E_FAIL);
350 ChkDR(DRM_DWordAdd(ibCur, SIZEOF(DRM_WORD), &dwResult));
351 ChkBufferSize(dwResult, f_cbInitData);
352 NETWORKBYTES_TO_WORD(wVersion, f_pbInitData, ibCur);
356 ChkDR(DRM_DWordAdd(ibCur, SIZEOF(DRM_WORD), &dwResult));
357 ChkBufferSize(dwResult, f_cbInitData);
358 NETWORKBYTES_TO_WORD(wFlags, f_pbInitData, ibCur);
361 ChkDR(DRM_DWordAdd(ibCur, SIZEOF(DRM_GUID), &dwResult));
362 ChkBufferSize(dwResult, f_cbInitData);
367 ibCur, &guidSystemID));
375 ChkDR(DRM_DWordAdd(ibCur, SIZEOF(DRM_DWORD), &dwResult));
376 ChkBufferSize(dwResult, f_cbInitData);
377 NETWORKBYTES_TO_DWORD(cKids, f_pbInitData, ibCur);
382 ChkDR(DRM_DWordMult(cKids, SIZEOF(DRM_GUID), &dwResult));
383 ChkDR(DRM_DWordAdd(ibCur, dwResult, &dwResult));
384 ChkBufferSize(dwResult, f_cbInitData);
387 cbMultiKid = SIZEOF(DRM_DWORD) + (cKids * SIZEOF(DRM_GUID));
390 ChkDR(DRM_DWordAdd(ibCur, SIZEOF(DRM_DWORD), &dwResult));
391 ChkBufferSize(dwResult, f_cbInitData);
392 NETWORKBYTES_TO_DWORD(cbSystemSize, f_pbInitData, ibCur);
396 ChkDR(DRM_DWordAdd(ibCur, cbSystemSize, &dwResult));
397 ChkBufferSize(dwResult, f_cbInitData);
400 if (MEMCMP(&guidSystemID, &CLSID_PlayReadyProtectionSystemID,
401 SIZEOF(DRM_GUID)) == 0)
420 cbSystemSize + SIZEOF(cbSize) + SIZEOF(dwType)
421 + SIZEOF(DRM_GUID) + SIZEOF(wVersion) + SIZEOF(wFlags)
422 + SIZEOF(DRM_GUID) + SIZEOF(cbSystemSize) == cbSize,
427 cbSystemSize + SIZEOF(cbSize) + SIZEOF(dwType)
428 + SIZEOF(wVersion) + SIZEOF(wFlags) + SIZEOF(DRM_GUID)
429 + SIZEOF(cbSystemSize) + cbMultiKid == cbSize,
434 *f_pcbPRO = cbSystemSize;
436 ErrorExit:
return drm_res;
443 uint32_t f_cbInitData)
445 DRM_RESULT drm_res = DRM_SUCCESS;
447 DRM_BYTE *pbPRO = NULL;
450 ChkArg(f_pbInitData != NULL && f_cbInitData > 0);
460 ChkBOOL(cbPRO > 0, DRM_E_FAIL);
461 ChkMem(pbPRO = (DRM_BYTE *) Oem_MemAlloc(cbPRO));
463 MEMCPY(pbPRO, f_pbInitData + ibPRO, cbPRO);
480 DRM_RESULT drm_res = DRM_SUCCESS;
481 DRM_DWORD cchDestURL = 0;
482 DRM_ANSI_STRING dastrCustomData = EMPTY_DRM_STRING;
488 drm_res = Drm_LicenseAcq_GenerateChallenge(m_ptrAppContext, g_rgpdstrRights,
489 sizeof(g_rgpdstrRights) /
sizeof(DRM_CONST_STRING *),
496 NULL, &m_cbChallenge);
498 if (drm_res == DRM_E_BUFFERTOOSMALL)
503 m_ptrDestURL = (DRM_CHAR *) Oem_MemAlloc(
505 ZEROMEM(m_ptrDestURL, cchDestURL + 1);
510 if (m_cbChallenge > 0)
511 ChkMem(m_pbChallenge = (DRM_BYTE *) Oem_MemAlloc(m_cbChallenge));
513 drm_res = DRM_SUCCESS;
518 cout <<
"aampGenerateKeyRequest :: Playready challenge generated" << endl;
523 Drm_LicenseAcq_GenerateChallenge(m_ptrAppContext, g_rgpdstrRights,
524 sizeof(g_rgpdstrRights) /
sizeof(DRM_CONST_STRING *),
528 m_ptrDestURL, &cchDestURL,
530 NULL, m_pbChallenge, &m_cbChallenge));
532 AAMPLOG_WARN(
"aampGenerateKeyRequest :: Playready destination URL : %s ", m_ptrDestURL);
536 result =
new DrmData(m_pbChallenge, m_cbChallenge);
537 destinationURL =
static_cast<string>(m_ptrDestURL);
541 if (DRM_FAILED(drm_res))
543 AAMPLOG_WARN(
"aampGenerateKeyRequest :: Playread DRM key request generation failed error code : %08x ", drm_res);
556 AAMPLOG_ERR(
"PlayReadyDRMSession: Cannot Process Null Key ");
561 cout <<
"aampDRMProcessKey :: Playready Update" << endl;
563 DRM_RESULT drm_res = DRM_SUCCESS;
564 DRM_LICENSE_RESPONSE oLicenseResp =
565 { eUnknownProtocol, 0 };
569 ChkBOOL(m_eKeyState ==
KEY_PENDING, DRM_E_INVALIDARG);
571 cout <<
"aampDRMProcessKey :: Playready check if msg is null" << endl;
576 drm_res = Drm_LicenseAcq_ProcessResponse(m_ptrAppContext,
577 DRM_PROCESS_LIC_RESPONSE_SIGNATURE_NOT_REQUIRED,
579 NULL, (DRM_BYTE *)(key->
getData().c_str()),
582 printf(
"aampDRMProcessKey :: Drm_LicenseAcq_ProcessResponse result : %08x ", drm_res);
587 drm_res = Drm_Reader_Bind(m_ptrAppContext, g_rgpdstrRights,
588 NO_OF(g_rgpdstrRights), m_pOutputProtection->PR_OP_Callback,
589 m_pOutputProtection->getPlayReadyLevels(), &m_oDecryptContext);
591 AAMPLOG_WARN(
"aampDRMProcessKey :: Printing bind result : %08x ", drm_res);
596 AAMPLOG_WARN(
"aampDRMProcessKey :: Key processed, now ready for content decryption");
600 ErrorExit:
if (DRM_FAILED(drm_res))
602 AAMPLOG_ERR(
"aampDRMProcessKey :: Playready failed processing license response : error code : %08x ", drm_res);
613 const uint8_t *payloadData, uint32_t payloadDataSize, uint8_t **ppOpaqueData)
617 DRM_AES_COUNTER_MODE_CONTEXT oAESContext =
619 DRM_RESULT drm_res = DRM_SUCCESS;
620 DRM_RESULT err = DRM_SUCCESS;
622 cout <<
"PR decrypt :: Playready Decrypt invoked" << endl;
624 uint8_t *ivData = (uint8_t *) f_pbIV;
632 AAMPLOG_WARN(
"UHD source but not HDCP 2.2. FAILING decrypt\n");
633 return HDCP_COMPLIANCE_CHECK_FAILURE;
637 pthread_mutex_lock(&decryptMutex);
638 ChkDR(Drm_Reader_InitDecrypt(&m_oDecryptContext, NULL, 0));
641 for (uint32_t i = 0; i < f_cbIV / 2; i++)
644 ivData[i] = ivData[f_cbIV - i - 1];
645 ivData[f_cbIV - i - 1] = temp;
648 MEMCPY(&oAESContext.qwInitializationVector, ivData, f_cbIV);
656 OEM_OPAQUE_BUFFER_HANDLE hOpaqueBufferIn;
657 OEM_OPAQUE_BUFFER_HANDLE hOpaqueBufferOut;
658 OEM_HAL_OpaqueBufferCreateWithPointer((DRM_BYTE *)payloadData, payloadDataSize, &hOpaqueBufferIn);
659 OEM_HAL_OpaqueBufferCreate(&hOpaqueBufferOut);
661 err = Drm_Reader_DecryptOpaque(&m_oDecryptContext,
667 DRM_RESULT errHandle = OEM_HAL_OpaqueBufferGetDataHandle(hOpaqueBufferOut, ppOpaqueData);
668 if (DRM_FAILED(errHandle)) {
669 AAMPLOG_ERR(
"AampDRMSession::decrypt --> OEM_HAL_OpaqueBufferGetDataHandle FAILED errHandle = %X, opaqueData = %p",
670 errHandle, *ppOpaqueData);
673 OEM_HAL_OpaqueBufferDestroy(&hOpaqueBufferIn);
674 OEM_HAL_OpaqueBufferDestroy(&hOpaqueBufferOut);
678 err = Drm_Reader_Decrypt(&m_oDecryptContext, &oAESContext,
679 (DRM_BYTE *) payloadData, payloadDataSize);
680 *ppOpaqueData = NULL;
689 ChkDR(Drm_Reader_Commit(m_ptrAppContext, m_pOutputProtection->PR_OP_Callback, m_pOutputProtection->getPlayReadyLevels() ));
692 pthread_mutex_unlock(&decryptMutex);
694 cout <<
"Playready Decrypt return clear content" << endl;
702 pthread_mutex_unlock(&decryptMutex);
703 AAMPLOG_ERR(
"PR decrypt :: Play ready session : Decrypt Error");
722 Drm_Reader_Close(&m_oDecryptContext);
723 Drm_Reinitialize(m_ptrAppContext);
724 SAFE_OEM_FREE(m_pbChallenge);
725 SAFE_OEM_FREE(m_ptrDestURL);
726 m_pbChallenge = NULL;
732 SAFE_OEM_FREE(m_pbPRO);