1*54e60f84SAndroid Build Coastguard Worker /* 2*54e60f84SAndroid Build Coastguard Worker * Copyright (c) 2020 Intel Corporation. All Rights Reserved. 3*54e60f84SAndroid Build Coastguard Worker * 4*54e60f84SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a 5*54e60f84SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the 6*54e60f84SAndroid Build Coastguard Worker * "Software"), to deal in the Software without restriction, including 7*54e60f84SAndroid Build Coastguard Worker * without limitation the rights to use, copy, modify, merge, publish, 8*54e60f84SAndroid Build Coastguard Worker * distribute, sub license, and/or sell copies of the Software, and to 9*54e60f84SAndroid Build Coastguard Worker * permit persons to whom the Software is furnished to do so, subject to 10*54e60f84SAndroid Build Coastguard Worker * the following conditions: 11*54e60f84SAndroid Build Coastguard Worker * 12*54e60f84SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the 13*54e60f84SAndroid Build Coastguard Worker * next paragraph) shall be included in all copies or substantial portions 14*54e60f84SAndroid Build Coastguard Worker * of the Software. 15*54e60f84SAndroid Build Coastguard Worker * 16*54e60f84SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17*54e60f84SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18*54e60f84SAndroid Build Coastguard Worker * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 19*54e60f84SAndroid Build Coastguard Worker * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR 20*54e60f84SAndroid Build Coastguard Worker * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21*54e60f84SAndroid Build Coastguard Worker * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22*54e60f84SAndroid Build Coastguard Worker * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23*54e60f84SAndroid Build Coastguard Worker */ 24*54e60f84SAndroid Build Coastguard Worker 25*54e60f84SAndroid Build Coastguard Worker /** 26*54e60f84SAndroid Build Coastguard Worker * \file va_prot.h 27*54e60f84SAndroid Build Coastguard Worker * \brief Protected content API. 28*54e60f84SAndroid Build Coastguard Worker * 29*54e60f84SAndroid Build Coastguard Worker * This file contains the \ref api_prot "Protected content API". 30*54e60f84SAndroid Build Coastguard Worker */ 31*54e60f84SAndroid Build Coastguard Worker 32*54e60f84SAndroid Build Coastguard Worker #ifndef VA_PROT_H 33*54e60f84SAndroid Build Coastguard Worker #define VA_PROT_H 34*54e60f84SAndroid Build Coastguard Worker 35*54e60f84SAndroid Build Coastguard Worker #ifdef __cplusplus 36*54e60f84SAndroid Build Coastguard Worker extern "C" { 37*54e60f84SAndroid Build Coastguard Worker #endif 38*54e60f84SAndroid Build Coastguard Worker 39*54e60f84SAndroid Build Coastguard Worker /** 40*54e60f84SAndroid Build Coastguard Worker * \defgroup api_prot Protected content API 41*54e60f84SAndroid Build Coastguard Worker * 42*54e60f84SAndroid Build Coastguard Worker * @{ 43*54e60f84SAndroid Build Coastguard Worker * \section prolouge Prolouge 44*54e60f84SAndroid Build Coastguard Worker * Video streaming is ubiquitous and the support for video streaming is widely 45*54e60f84SAndroid Build Coastguard Worker * available across client open systems such as PCs, MACs, Chromebooks etc. and 46*54e60f84SAndroid Build Coastguard Worker * closed systems such as settop box, smart TVs, DVDs etc. By default, 47*54e60f84SAndroid Build Coastguard Worker * video streaming is not considered premium due to various constraints such as 48*54e60f84SAndroid Build Coastguard Worker * resolution, quality, production cost etc. but recently streaming of premium 49*54e60f84SAndroid Build Coastguard Worker * video(1080p+) has become norm. The streaming of premium video in open systems 50*54e60f84SAndroid Build Coastguard Worker * such as PCs, MACs, Chromebooks etc. makes video particularly susceptible to 51*54e60f84SAndroid Build Coastguard Worker * piracy (due to non-video playback usages of such systems) resulting in 52*54e60f84SAndroid Build Coastguard Worker * millions of dollars of loss to content creators. 53*54e60f84SAndroid Build Coastguard Worker * 54*54e60f84SAndroid Build Coastguard Worker * Digital Rights Management(DRM) has been proposed to stop piracy of premium 55*54e60f84SAndroid Build Coastguard Worker * video streams across a wide spectrum. There are some known open/closed DRM 56*54e60f84SAndroid Build Coastguard Worker * standards such as [Widevine by Google](https://www.widevine.com/), 57*54e60f84SAndroid Build Coastguard Worker * [PlayReady by Microsoft](https://www.microsoft.com/playready/), 58*54e60f84SAndroid Build Coastguard Worker * [FairPlay by Apple](https://developer.apple.com/streaming/fps/), 59*54e60f84SAndroid Build Coastguard Worker * [Merlin by Sony](https://www.marlin-community.com/), etc... Each DRM 60*54e60f84SAndroid Build Coastguard Worker * standard has its properties but all DRM standards support a common 61*54e60f84SAndroid Build Coastguard Worker * mechanism. This common mechanism involves cryptographical method for 62*54e60f84SAndroid Build Coastguard Worker * authenticating the client system, delivering bitstream and required 63*54e60f84SAndroid Build Coastguard Worker * cryptographic assets to client system and then cryptographically processing 64*54e60f84SAndroid Build Coastguard Worker * bitstream in client system. The cryptographic methods used in these steps 65*54e60f84SAndroid Build Coastguard Worker * are asymmetric such as RSA, DH etc. and symmetric such as AES CTR, CBC etc. 66*54e60f84SAndroid Build Coastguard Worker * encryption mechanisms. The authentication of client system, delivery of 67*54e60f84SAndroid Build Coastguard Worker * bitstream and cryptographic assets to client system is performed using 68*54e60f84SAndroid Build Coastguard Worker * asymmetric cryptographic mechanism while bitstream is encrypted and processed 69*54e60f84SAndroid Build Coastguard Worker * using symmetric cryptographic. In DRM world, authentication of client system, 70*54e60f84SAndroid Build Coastguard Worker * delivery of bitstream and required cryptographic assets to client system is 71*54e60f84SAndroid Build Coastguard Worker * loosely called provisioning and license acquisition while the processing of 72*54e60f84SAndroid Build Coastguard Worker * cryptographically secure bitstream is divided as video decryption/decoding, 73*54e60f84SAndroid Build Coastguard Worker * audio decryption/playback, video display. Besides DRM standards, Video/Audio 74*54e60f84SAndroid Build Coastguard Worker * bitstream encryption standard such as 75*54e60f84SAndroid Build Coastguard Worker * [Common Encryption Standard(CENC)](https://www.iso.org/standard/76597.html) 76*54e60f84SAndroid Build Coastguard Worker * provides a mechanism to normalize bitstream encryption methods across vendors 77*54e60f84SAndroid Build Coastguard Worker * while providing flexibility. 78*54e60f84SAndroid Build Coastguard Worker * 79*54e60f84SAndroid Build Coastguard Worker * \section DRM Pipeline 80*54e60f84SAndroid Build Coastguard Worker * Most DRM standards execute the following deep pipeline to playback 81*54e60f84SAndroid Build Coastguard Worker * contents on client systems from streaming servers - provisioning uses 82*54e60f84SAndroid Build Coastguard Worker * provisioning servers, licence aquisition uses license servers, video 83*54e60f84SAndroid Build Coastguard Worker * bitstream delivery uses content servers and decryption/decoding, audio 84*54e60f84SAndroid Build Coastguard Worker * bitstream delivery uses content servers and decyption/playback, 85*54e60f84SAndroid Build Coastguard Worker * display/playback. The system level HWDRM sequence diagram is following - 86*54e60f84SAndroid Build Coastguard Worker *  87*54e60f84SAndroid Build Coastguard Worker * and HWDRM pipeline view is following - 88*54e60f84SAndroid Build Coastguard Worker *  89*54e60f84SAndroid Build Coastguard Worker * 90*54e60f84SAndroid Build Coastguard Worker * \section LibVA Protected Content APIs 91*54e60f84SAndroid Build Coastguard Worker * The LibVA Protected APIs are designed to enable DRM capabilities or 92*54e60f84SAndroid Build Coastguard Worker * facilitate isolated communicaiton with TEE. 93*54e60f84SAndroid Build Coastguard Worker * The VAEntrypointProtectedTEEComm is to define interfaces for Application 94*54e60f84SAndroid Build Coastguard Worker * to TEE direct communication to perform various TEE centric operations 95*54e60f84SAndroid Build Coastguard Worker * such as standalone provisioning of platform at factory or provisioning 96*54e60f84SAndroid Build Coastguard Worker * TEE for other usages, providing TEE capabilities etc. 97*54e60f84SAndroid Build Coastguard Worker * The VAEntrypointProtectedContent is to define interfaces for protected 98*54e60f84SAndroid Build Coastguard Worker * video playback using HWDRM. This entry point co-ordinates assets across 99*54e60f84SAndroid Build Coastguard Worker * TEE/GPU/Display for HWDRM playback. 100*54e60f84SAndroid Build Coastguard Worker * 101*54e60f84SAndroid Build Coastguard Worker * The difference between Protected Content and Protected TEE Communication 102*54e60f84SAndroid Build Coastguard Worker * is that Protected Content Entrypoint does not provide isolated entry 103*54e60f84SAndroid Build Coastguard Worker * point for TEE and invokes TEE only from HWDRM perspective. 104*54e60f84SAndroid Build Coastguard Worker * 105*54e60f84SAndroid Build Coastguard Worker * Protected Content Entrypoint 106*54e60f84SAndroid Build Coastguard Worker * The most of DRM standards execute following deep pipeline to playback 107*54e60f84SAndroid Build Coastguard Worker * contents on client systems from streaming servers - provisioning uses 108*54e60f84SAndroid Build Coastguard Worker * provisioning servers, licence aquisition uses license servers, video 109*54e60f84SAndroid Build Coastguard Worker * bitstream delivery uses content servers and decryption/decoding, audio 110*54e60f84SAndroid Build Coastguard Worker * bitstream delivery uses content servers and decyption/playback, 111*54e60f84SAndroid Build Coastguard Worker * display/playback. 112*54e60f84SAndroid Build Coastguard Worker * 113*54e60f84SAndroid Build Coastguard Worker * The Provisioning and License aquisition implementations are Independent 114*54e60f84SAndroid Build Coastguard Worker * Hardware Vendor (IHV) specific but most IHVs use some form of Trusted 115*54e60f84SAndroid Build Coastguard Worker * Execution Environment (TEE) to prepare client platform or system for DRM 116*54e60f84SAndroid Build Coastguard Worker * content playback. The provisioning operations use provisioning servers (as 117*54e60f84SAndroid Build Coastguard Worker * instructed in DRM standard) and client system TEE. The communication between 118*54e60f84SAndroid Build Coastguard Worker * provisioning servers and client system TEE uses asymmetic cryptographic 119*54e60f84SAndroid Build Coastguard Worker * mechanism. This step provides a way to establish root-of-trust between 120*54e60f84SAndroid Build Coastguard Worker * client system and streaming servers. Once root-of-trust is established then 121*54e60f84SAndroid Build Coastguard Worker * client system requests for license aquisition for a particular streaming 122*54e60f84SAndroid Build Coastguard Worker * title. The license aquisition involves communication between licensing 123*54e60f84SAndroid Build Coastguard Worker * servers and TEE using asymmetic cryptographic mechanism. At end of this step, 124*54e60f84SAndroid Build Coastguard Worker * client system TEE has required assets to decrypt/decode. Although these 125*54e60f84SAndroid Build Coastguard Worker * communication does not direcly involve video aspect of GPU but **facilitate 126*54e60f84SAndroid Build Coastguard Worker * GPU required assets to playback premium contents**. 127*54e60f84SAndroid Build Coastguard Worker * 128*54e60f84SAndroid Build Coastguard Worker * To support DRM standard requirements in playback pipeline, OSes and HWs 129*54e60f84SAndroid Build Coastguard Worker * incorporate various methods to protect full playback pipeline. These 130*54e60f84SAndroid Build Coastguard Worker * methods of protection could be SW based or HW based. The SW based protection 131*54e60f84SAndroid Build Coastguard Worker * mechanism of DRMs is called SWDRM while HW based protection mechanism is 132*54e60f84SAndroid Build Coastguard Worker * called HWDRM. There is no previous support in LibVA to support either DRM 133*54e60f84SAndroid Build Coastguard Worker * mechanism. 134*54e60f84SAndroid Build Coastguard Worker * 135*54e60f84SAndroid Build Coastguard Worker * For DRM capabilities, APIs inolve creation of protected session to 136*54e60f84SAndroid Build Coastguard Worker * communicate with TEE and then using these protected sessions to process 137*54e60f84SAndroid Build Coastguard Worker * video/audio data. The philophashy behind these API is to leverage existing 138*54e60f84SAndroid Build Coastguard Worker * LibVA infrastructure as much as possible. 139*54e60f84SAndroid Build Coastguard Worker * 140*54e60f84SAndroid Build Coastguard Worker * Note: TEE could be any secure HW device such as ME-FW or FPGA Secure 141*54e60f84SAndroid Build Coastguard Worker * Enclave or NPU Secure Enclave. There are 2 concepts here – TEE Type such 142*54e60f84SAndroid Build Coastguard Worker * as ME-FW or FPGA or NPU; TEE Type Client such as for AMT or HDCP or 143*54e60f84SAndroid Build Coastguard Worker * something else etc. 144*54e60f84SAndroid Build Coastguard Worker * 145*54e60f84SAndroid Build Coastguard Worker * \section description Detailed Description 146*54e60f84SAndroid Build Coastguard Worker * The Protected content API provides a general mechanism for opening 147*54e60f84SAndroid Build Coastguard Worker * protected session with TEE and if required then \ref priming GPU/Display. 148*54e60f84SAndroid Build Coastguard Worker * The behavior of protected session API depends on parameterization/ 149*54e60f84SAndroid Build Coastguard Worker * configuration of protected session. Just for TEE tasks, protected 150*54e60f84SAndroid Build Coastguard Worker * session is parameterized/configured as TEE Communication while for 151*54e60f84SAndroid Build Coastguard Worker * HWDRM, protected session is parameterized/confgured as Protected 152*54e60f84SAndroid Build Coastguard Worker * Content. 153*54e60f84SAndroid Build Coastguard Worker * 154*54e60f84SAndroid Build Coastguard Worker * TEE Communication Entrypoint 155*54e60f84SAndroid Build Coastguard Worker * With TEE Communication parameterization/configuration, client 156*54e60f84SAndroid Build Coastguard Worker * executes TEE workloads in TEE with TEE Communication protected 157*54e60f84SAndroid Build Coastguard Worker * session. 158*54e60f84SAndroid Build Coastguard Worker * 159*54e60f84SAndroid Build Coastguard Worker * Protected Content Entrypoint 160*54e60f84SAndroid Build Coastguard Worker * With Protected Content parameterization/configuration, client 161*54e60f84SAndroid Build Coastguard Worker * executes HWDRM playback workloads HW accelerating protected video 162*54e60f84SAndroid Build Coastguard Worker * content decryption/decoding with protected content session. 163*54e60f84SAndroid Build Coastguard Worker * 164*54e60f84SAndroid Build Coastguard Worker * Before calling vaCreateProtectedSession, VAConfigID is obtained using 165*54e60f84SAndroid Build Coastguard Worker * existing libva mechanism to determine configuration parameters of 166*54e60f84SAndroid Build Coastguard Worker * protected session. The VAConfigID is determined in this way so that 167*54e60f84SAndroid Build Coastguard Worker * Protected Session implementation aligns with existing libva implementation. 168*54e60f84SAndroid Build Coastguard Worker * After obtaining VAConfigID, Protected Session needs to be created but 169*54e60f84SAndroid Build Coastguard Worker * note this is a session and not a context. Refer VAProtectedSessionID 170*54e60f84SAndroid Build Coastguard Worker * for more details. 171*54e60f84SAndroid Build Coastguard Worker * 172*54e60f84SAndroid Build Coastguard Worker * Note:- Protected session represents session object that has all security 173*54e60f84SAndroid Build Coastguard Worker * information needed for Secure Enclave to operate certain operations. 174*54e60f84SAndroid Build Coastguard Worker * 175*54e60f84SAndroid Build Coastguard Worker * \subsection priming Priming 176*54e60f84SAndroid Build Coastguard Worker * Priming is used to refer various types of initializations. For example, 177*54e60f84SAndroid Build Coastguard Worker * if license acquisition is being performed then priming means that TEE is 178*54e60f84SAndroid Build Coastguard Worker * already provisioned aka TEE has some sort of "cryptographic" whitelist of 179*54e60f84SAndroid Build Coastguard Worker * servers that TEE will use to do license acquisition for video playback. If 180*54e60f84SAndroid Build Coastguard Worker * HWDRM video playback is being performed then priming means that HWDRM 181*54e60f84SAndroid Build Coastguard Worker * eco-system TEE/GPU/Display has proper keys to do proper video playback etc. 182*54e60f84SAndroid Build Coastguard Worker * 183*54e60f84SAndroid Build Coastguard Worker * Protected content API uses the following paradigm for protected content 184*54e60f84SAndroid Build Coastguard Worker * session: 185*54e60f84SAndroid Build Coastguard Worker * - \ref api_pc_caps 186*54e60f84SAndroid Build Coastguard Worker * - \ref api_pc_setup 187*54e60f84SAndroid Build Coastguard Worker * - \ref api_pc_exec 188*54e60f84SAndroid Build Coastguard Worker * - \ref api_pc_attach 189*54e60f84SAndroid Build Coastguard Worker * 190*54e60f84SAndroid Build Coastguard Worker * \subsection api_pc_caps Query for supported cipher mode, block size, mode 191*54e60f84SAndroid Build Coastguard Worker * 192*54e60f84SAndroid Build Coastguard Worker * Checking whether protected content is supported can be performed with 193*54e60f84SAndroid Build Coastguard Worker * vaQueryConfigEntrypoints() and the profile argument set to 194*54e60f84SAndroid Build Coastguard Worker * #VAProfileProtected. If protected content is supported, then the list of 195*54e60f84SAndroid Build Coastguard Worker * returned entry-points will include #VAEntrypointProtectedContent 196*54e60f84SAndroid Build Coastguard Worker * 197*54e60f84SAndroid Build Coastguard Worker * \code 198*54e60f84SAndroid Build Coastguard Worker * VAEntrypoint *entrypoints; 199*54e60f84SAndroid Build Coastguard Worker * int i, num_entrypoints, supportsProtectedContent = 0; 200*54e60f84SAndroid Build Coastguard Worker * 201*54e60f84SAndroid Build Coastguard Worker * num_entrypoints = vaMaxNumEntrypoints(); 202*54e60f84SAndroid Build Coastguard Worker * entrypoints = malloc(num_entrypoints * sizeof(entrypoints[0]); 203*54e60f84SAndroid Build Coastguard Worker * vaQueryConfigEntrypoints(va_dpy, VAProfileProtected, entrypoints, 204*54e60f84SAndroid Build Coastguard Worker * &num_entrypoints); 205*54e60f84SAndroid Build Coastguard Worker * 206*54e60f84SAndroid Build Coastguard Worker * for (i = 0; !supportsProtectedContent && i < num_entrypoints; i++) { 207*54e60f84SAndroid Build Coastguard Worker * if (entrypoints[i] == VAEntrypointProtectedContent) 208*54e60f84SAndroid Build Coastguard Worker * supportsProtectedContent = 1; 209*54e60f84SAndroid Build Coastguard Worker * } 210*54e60f84SAndroid Build Coastguard Worker * \endcode 211*54e60f84SAndroid Build Coastguard Worker * 212*54e60f84SAndroid Build Coastguard Worker * Then, the vaGetConfigAttributes() function is used to query the protected 213*54e60f84SAndroid Build Coastguard Worker * session capabilities. 214*54e60f84SAndroid Build Coastguard Worker * 215*54e60f84SAndroid Build Coastguard Worker * \code 216*54e60f84SAndroid Build Coastguard Worker * VAConfigAttrib attribs; 217*54e60f84SAndroid Build Coastguard Worker * attribs[0].type = VAConfigAttribProtectedContentCipherAlgorithm; 218*54e60f84SAndroid Build Coastguard Worker * attribs[1].type = VAConfigAttribProtectedContentCipherBlockSize; 219*54e60f84SAndroid Build Coastguard Worker * attribs[2].type = VAConfigAttribProtectedContentCipherMode; 220*54e60f84SAndroid Build Coastguard Worker * attribs[3].type = VAConfigAttribProtectedContentCipherSampleType; 221*54e60f84SAndroid Build Coastguard Worker * attribs[4].type = VAConfigAttribProtectedContentUsage; 222*54e60f84SAndroid Build Coastguard Worker * vaGetConfigAttributes(va_dpy, VAProfileProtected, 223*54e60f84SAndroid Build Coastguard Worker * VAEntrypointProtectedContent, attribs, 5); 224*54e60f84SAndroid Build Coastguard Worker * if ((attribs[1].value & VA_PC_CIPHER_AES) == 0) { 225*54e60f84SAndroid Build Coastguard Worker * // not find desired cipher algorithm 226*54e60f84SAndroid Build Coastguard Worker * assert(0); 227*54e60f84SAndroid Build Coastguard Worker * } 228*54e60f84SAndroid Build Coastguard Worker * if ((attribs[2].value & VA_PC_BLOCK_SIZE_128) == 0) { 229*54e60f84SAndroid Build Coastguard Worker * // not find desired block size 230*54e60f84SAndroid Build Coastguard Worker * assert(0); 231*54e60f84SAndroid Build Coastguard Worker * } 232*54e60f84SAndroid Build Coastguard Worker * if ((attribs[3].value & VA_PC_CIPHER_MODE_CBC) == 0) { 233*54e60f84SAndroid Build Coastguard Worker * // not find desired counter mode 234*54e60f84SAndroid Build Coastguard Worker * assert(0); 235*54e60f84SAndroid Build Coastguard Worker * } 236*54e60f84SAndroid Build Coastguard Worker * if ((attribs[4].value & VA_PC_SAMPLE_TYPE_SUBSAMPLE) == 0) { 237*54e60f84SAndroid Build Coastguard Worker * // not find desired sample type 238*54e60f84SAndroid Build Coastguard Worker * assert(0); 239*54e60f84SAndroid Build Coastguard Worker * } 240*54e60f84SAndroid Build Coastguard Worker * if ((attribs[5].value & VA_PC_USAGE_WIDEVINE) == 0) { 241*54e60f84SAndroid Build Coastguard Worker * // not find desired usage 242*54e60f84SAndroid Build Coastguard Worker * assert(0); 243*54e60f84SAndroid Build Coastguard Worker * } 244*54e60f84SAndroid Build Coastguard Worker * \endcode 245*54e60f84SAndroid Build Coastguard Worker * 246*54e60f84SAndroid Build Coastguard Worker * \subsection api_pc_setup Set up a protected content session 247*54e60f84SAndroid Build Coastguard Worker * 248*54e60f84SAndroid Build Coastguard Worker * TEE Communication Entrypoint 249*54e60f84SAndroid Build Coastguard Worker * The protected content session provides a TEE session that is used to extract 250*54e60f84SAndroid Build Coastguard Worker * TEE information. This information could be used to peform TEE operations. 251*54e60f84SAndroid Build Coastguard Worker * 252*54e60f84SAndroid Build Coastguard Worker * Protected Content Entrypoint 253*54e60f84SAndroid Build Coastguard Worker * The protected content session can be attached to VA decode/encode/vp context 254*54e60f84SAndroid Build Coastguard Worker * to do decryption/protection in the pipeline. 255*54e60f84SAndroid Build Coastguard Worker * Before creating a protected content session, it needs to create a config 256*54e60f84SAndroid Build Coastguard Worker * first via vaCreateConfig(). Then using this config id to create a protected 257*54e60f84SAndroid Build Coastguard Worker * content session via vaCreateProtectedSession(). 258*54e60f84SAndroid Build Coastguard Worker * 259*54e60f84SAndroid Build Coastguard Worker * The general control flow is demonstrated by the following pseudo-code: 260*54e60f84SAndroid Build Coastguard Worker * \code 261*54e60f84SAndroid Build Coastguard Worker * // Create config 262*54e60f84SAndroid Build Coastguard Worker * VAConfigID config_id; 263*54e60f84SAndroid Build Coastguard Worker * 264*54e60f84SAndroid Build Coastguard Worker * attribs[0].value = VA_PC_CIPHER_AES; 265*54e60f84SAndroid Build Coastguard Worker * attribs[1].value = VA_PC_BLOCK_SIZE_128; 266*54e60f84SAndroid Build Coastguard Worker * attribs[2].value = VA_PC_CIPHER_MODE_CBC; 267*54e60f84SAndroid Build Coastguard Worker * attribs[3].value = VA_PC_SAMPLE_TYPE_SUBSAMPLE; 268*54e60f84SAndroid Build Coastguard Worker * attribs[4].value = VA_PC_USAGE_WIDEVINE; 269*54e60f84SAndroid Build Coastguard Worker * va_status = vaCreateConfig(va_dpy, VAProfileProtected, 270*54e60f84SAndroid Build Coastguard Worker * VAEntrypointProtectedContent, attribs, 5, &config_id); 271*54e60f84SAndroid Build Coastguard Worker * CHECK_VASTATUS(va_status, "vaCreateConfig"); 272*54e60f84SAndroid Build Coastguard Worker * \endcode 273*54e60f84SAndroid Build Coastguard Worker * 274*54e60f84SAndroid Build Coastguard Worker * Once the config is set up, we can create protected content session via 275*54e60f84SAndroid Build Coastguard Worker vaCreateProtectedSession(). 276*54e60f84SAndroid Build Coastguard Worker * \code 277*54e60f84SAndroid Build Coastguard Worker * // Create a protected session 278*54e60f84SAndroid Build Coastguard Worker * VAProtectedSessionID crypto_session; 279*54e60f84SAndroid Build Coastguard Worker * 280*54e60f84SAndroid Build Coastguard Worker * va_status = vaCreateProtectedSession(va_dpy, config_id, &crypto_session); 281*54e60f84SAndroid Build Coastguard Worker * CHECK_VASTATUS(va_status, "vaCreateProtectedSession"); 282*54e60f84SAndroid Build Coastguard Worker * \endcode 283*54e60f84SAndroid Build Coastguard Worker * 284*54e60f84SAndroid Build Coastguard Worker * \subsection api_pc_exec TEE communication via vaProtectedSessionExecute() 285*54e60f84SAndroid Build Coastguard Worker * 286*54e60f84SAndroid Build Coastguard Worker * TEE Communication Entrypoint 287*54e60f84SAndroid Build Coastguard Worker * App needs to communicate with TEE to get TEE information or \ref priming 288*54e60f84SAndroid Build Coastguard Worker * "prime" TEE with information that will be utilized for future TEE 289*54e60f84SAndroid Build Coastguard Worker * operations/tasks. 290*54e60f84SAndroid Build Coastguard Worker * 291*54e60f84SAndroid Build Coastguard Worker * Protected Content Entrypoint 292*54e60f84SAndroid Build Coastguard Worker * Before starting decryption/encryption operation in GPU, app may need to 293*54e60f84SAndroid Build Coastguard Worker * communicate with TEE to get encrypted assets for \ref priming HWDRM pipeline 294*54e60f84SAndroid Build Coastguard Worker * for decryption. App need to call vaProtectedSessionExecute() to get this 295*54e60f84SAndroid Build Coastguard Worker * asset. The following pseudo-code demonstrates getting session assets via 296*54e60f84SAndroid Build Coastguard Worker * vaProtectedSessionExecute() as an example. 297*54e60f84SAndroid Build Coastguard Worker * 298*54e60f84SAndroid Build Coastguard Worker * In this example, the vaCreateBuffer is called with exec_buffer mainly becasue TEE 299*54e60f84SAndroid Build Coastguard Worker * Communication Entrypoint buffers are CPU bound and buffer size is small enough to 300*54e60f84SAndroid Build Coastguard Worker * have extra copy operation without impacting performance. 301*54e60f84SAndroid Build Coastguard Worker * 302*54e60f84SAndroid Build Coastguard Worker * \code 303*54e60f84SAndroid Build Coastguard Worker * uint32_t app_id = 0xFF; 304*54e60f84SAndroid Build Coastguard Worker * VABufferID buffer; 305*54e60f84SAndroid Build Coastguard Worker * VAProtectedSessionExecuteBuffer exec_buff = {0}; 306*54e60f84SAndroid Build Coastguard Worker * 307*54e60f84SAndroid Build Coastguard Worker * exec_buff.function_id = GET_SESSION_ID; 308*54e60f84SAndroid Build Coastguard Worker * exec_buff.input.data = nullptr; 309*54e60f84SAndroid Build Coastguard Worker * exec_buff.input.data_size = 0; 310*54e60f84SAndroid Build Coastguard Worker * exec_buff.output.data = &app_id; 311*54e60f84SAndroid Build Coastguard Worker * exec_buff.output.max_data_size = sizeof(app_id); 312*54e60f84SAndroid Build Coastguard Worker * va_status = vaCreateBuffer( 313*54e60f84SAndroid Build Coastguard Worker * va_dpy, 314*54e60f84SAndroid Build Coastguard Worker * crypto_session, 315*54e60f84SAndroid Build Coastguard Worker * (VABufferType) VAProtectedSessionExecuteBufferType, 316*54e60f84SAndroid Build Coastguard Worker * sizeof(exec_buff), 317*54e60f84SAndroid Build Coastguard Worker * 1, 318*54e60f84SAndroid Build Coastguard Worker * &exec_buff, 319*54e60f84SAndroid Build Coastguard Worker * &buffer); 320*54e60f84SAndroid Build Coastguard Worker * 321*54e60f84SAndroid Build Coastguard Worker * va_status = vaProtectedSessionExecute(va_dpy, crypto_session, buffer); 322*54e60f84SAndroid Build Coastguard Worker * 323*54e60f84SAndroid Build Coastguard Worker * vaDestroyBuffer(va_dpy, buffer); 324*54e60f84SAndroid Build Coastguard Worker * \endcode 325*54e60f84SAndroid Build Coastguard Worker * 326*54e60f84SAndroid Build Coastguard Worker * \subsection api_pc_attach Attach/Detach protected content session to the VA 327*54e60f84SAndroid Build Coastguard Worker * context which want to enable/disable decryption/protection 328*54e60f84SAndroid Build Coastguard Worker * 329*54e60f84SAndroid Build Coastguard Worker * Protected content session is attached to VA decode/encode/vp context to 330*54e60f84SAndroid Build Coastguard Worker * enable protected decoding/encoding/video processing per frame or entire 331*54e60f84SAndroid Build Coastguard Worker * stream. If protected session attached per frame then application has 2 332*54e60f84SAndroid Build Coastguard Worker * options for decoding/encoding skip processing i.e. accomodating clear 333*54e60f84SAndroid Build Coastguard Worker * frames - 1. Application could do detach after each frame is processed 334*54e60f84SAndroid Build Coastguard Worker * to process clear frame 2. Application could remains attached to decode/ 335*54e60f84SAndroid Build Coastguard Worker * encode session but specify enryption byte length to 0. 336*54e60f84SAndroid Build Coastguard Worker * The video processing does not has option #2 mainly because API does 337*54e60f84SAndroid Build Coastguard Worker * not provide skip processing. 338*54e60f84SAndroid Build Coastguard Worker * 339*54e60f84SAndroid Build Coastguard Worker * \code 340*54e60f84SAndroid Build Coastguard Worker * vaAttachProtectedSession(va_dpy, decode_ctx, crypto_session); 341*54e60f84SAndroid Build Coastguard Worker * foreach (iteration) { 342*54e60f84SAndroid Build Coastguard Worker * vaBeginPicture(va_dpy, decode_ctx, surface); 343*54e60f84SAndroid Build Coastguard Worker * ... 344*54e60f84SAndroid Build Coastguard Worker * vaRenderPicture(va_dpy, decode_ctx, &buf_id1, 1); 345*54e60f84SAndroid Build Coastguard Worker * vaRenderPicture(va_dpy, decode_ctx, &buf_id2, 1); 346*54e60f84SAndroid Build Coastguard Worker * // Buffer holding encryption parameters, i.e. VAEncryptionParameterBufferType buffer 347*54e60f84SAndroid Build Coastguard Worker * vaRenderPicture(va_dpy, decode_ctx, &buf_id_enc_param, 1); 348*54e60f84SAndroid Build Coastguard Worker * ... 349*54e60f84SAndroid Build Coastguard Worker * vaEndPicture(va_dpy, decode_ctx); 350*54e60f84SAndroid Build Coastguard Worker * } 351*54e60f84SAndroid Build Coastguard Worker * vaDetachProtectedSession(va_dpy, decode_ctx); 352*54e60f84SAndroid Build Coastguard Worker * \endcode 353*54e60f84SAndroid Build Coastguard Worker * 354*54e60f84SAndroid Build Coastguard Worker * or it could be frame-by-frame attaching/detaching as following: 355*54e60f84SAndroid Build Coastguard Worker * 356*54e60f84SAndroid Build Coastguard Worker * \code 357*54e60f84SAndroid Build Coastguard Worker * foreach (iteration) { 358*54e60f84SAndroid Build Coastguard Worker * if (encrypted) 359*54e60f84SAndroid Build Coastguard Worker * vaAttachProtectedSession(va_dpy, decode_ctx, crypto_session); 360*54e60f84SAndroid Build Coastguard Worker 361*54e60f84SAndroid Build Coastguard Worker * vaBeginPicture(va_dpy, decode_ctx, surface); 362*54e60f84SAndroid Build Coastguard Worker * ... 363*54e60f84SAndroid Build Coastguard Worker * vaRenderPicture(va_dpy, decode_ctx, &buf_id1, 1); 364*54e60f84SAndroid Build Coastguard Worker * vaRenderPicture(va_dpy, decode_ctx, &buf_id2, 1); 365*54e60f84SAndroid Build Coastguard Worker * // Buffer holding encryption parameters, i.e. VAEncryptionParameterBufferType buffer 366*54e60f84SAndroid Build Coastguard Worker * vaRenderPicture(va_dpy, decode_ctx, &buf_id_enc_param, 1); 367*54e60f84SAndroid Build Coastguard Worker * ... 368*54e60f84SAndroid Build Coastguard Worker * vaEndPicture(va_dpy, decode_ctx); 369*54e60f84SAndroid Build Coastguard Worker * 370*54e60f84SAndroid Build Coastguard Worker * if (encrypted) 371*54e60f84SAndroid Build Coastguard Worker * vaDetachProtectedSession(va_dpy, decode_ctx); 372*54e60f84SAndroid Build Coastguard Worker 373*54e60f84SAndroid Build Coastguard Worker * // check encrypted variable for next frame 374*54e60f84SAndroid Build Coastguard Worker * } 375*54e60f84SAndroid Build Coastguard Worker * \endcode 376*54e60f84SAndroid Build Coastguard Worker */ 377*54e60f84SAndroid Build Coastguard Worker 378*54e60f84SAndroid Build Coastguard Worker /** 379*54e60f84SAndroid Build Coastguard Worker * ProtectedSessions and Contexts 380*54e60f84SAndroid Build Coastguard Worker * 381*54e60f84SAndroid Build Coastguard Worker * According to #VAContextID, Context represents a "virtual" video decode, 382*54e60f84SAndroid Build Coastguard Worker * encode or video processing pipeline. Surfaces are render targets for a given 383*54e60f84SAndroid Build Coastguard Worker * context. The data in the surfaces are not accessible to the client except if 384*54e60f84SAndroid Build Coastguard Worker * derived image is supported and the internal data format of the surface is 385*54e60f84SAndroid Build Coastguard Worker * implementation specific. Application can create a video decode, encode or 386*54e60f84SAndroid Build Coastguard Worker * processing context which represents a "virtualized" hardware device. 387*54e60f84SAndroid Build Coastguard Worker * 388*54e60f84SAndroid Build Coastguard Worker * Since Protected Session does not virtualize any HW device or build any 389*54e60f84SAndroid Build Coastguard Worker * pipeline but rather accessorize existing virtualized HW device or pipeline 390*54e60f84SAndroid Build Coastguard Worker * to operate in protected mode so we decided to create separate function. 391*54e60f84SAndroid Build Coastguard Worker * Beside this, a virtualized HW device or pipeline could own several protected 392*54e60f84SAndroid Build Coastguard Worker * sessions and operate in those protected modes without ever re-creating 393*54e60f84SAndroid Build Coastguard Worker * virtualization of HW device or re-building HW pipeline (an unique protected 394*54e60f84SAndroid Build Coastguard Worker * environment multiplexing capability in Intel HW). 395*54e60f84SAndroid Build Coastguard Worker * 396*54e60f84SAndroid Build Coastguard Worker * The returned protected_session represents a notion of Host and TEE clients 397*54e60f84SAndroid Build Coastguard Worker * while representing protection status in GPU and Display. 398*54e60f84SAndroid Build Coastguard Worker * 399*54e60f84SAndroid Build Coastguard Worker * Both contexts and protected sessions are identified by unique IDs and its 400*54e60f84SAndroid Build Coastguard Worker * implementation specific internals are kept opaque to the clients 401*54e60f84SAndroid Build Coastguard Worker */ 402*54e60f84SAndroid Build Coastguard Worker typedef VAGenericID VAProtectedSessionID; 403*54e60f84SAndroid Build Coastguard Worker 404*54e60f84SAndroid Build Coastguard Worker /** \brief TEE Execucte Function ID. */ 405*54e60f84SAndroid Build Coastguard Worker typedef enum _VA_TEE_EXEC_FUNCTION_ID { 406*54e60f84SAndroid Build Coastguard Worker VA_TEE_EXECUTE_FUNCTION_ID_PASS_THROUGH = 0x00000001, 407*54e60f84SAndroid Build Coastguard Worker VA_TEE_EXECUTE_FUNCTION_ID_GET_FIRMWARE_VERSION = 0x00000002, 408*54e60f84SAndroid Build Coastguard Worker 409*54e60f84SAndroid Build Coastguard Worker } VA_TEE_EXECUTE_FUNCTION_ID; 410*54e60f84SAndroid Build Coastguard Worker 411*54e60f84SAndroid Build Coastguard Worker /** \brief Input/Output buffer of VAProtectedSessionExecuteBuffer */ 412*54e60f84SAndroid Build Coastguard Worker typedef struct _VAProtectedSessionBuffer { 413*54e60f84SAndroid Build Coastguard Worker /* 414*54e60f84SAndroid Build Coastguard Worker * This is used when this buffer refer to output buffer. The maximum size of 415*54e60f84SAndroid Build Coastguard Worker * data that the driver can return in the output buffer. It is not used for 416*54e60f84SAndroid Build Coastguard Worker * input buffer. 417*54e60f84SAndroid Build Coastguard Worker */ 418*54e60f84SAndroid Build Coastguard Worker uint32_t max_data_size; 419*54e60f84SAndroid Build Coastguard Worker /* 420*54e60f84SAndroid Build Coastguard Worker * If it is used for input buffer, it is the size of the input data. If it is 421*54e60f84SAndroid Build Coastguard Worker * used for output buffer, it is the returns size of the output data written 422*54e60f84SAndroid Build Coastguard Worker * by the driver. 423*54e60f84SAndroid Build Coastguard Worker */ 424*54e60f84SAndroid Build Coastguard Worker uint32_t data_size; 425*54e60f84SAndroid Build Coastguard Worker /* 426*54e60f84SAndroid Build Coastguard Worker * data pointer of this buffer 427*54e60f84SAndroid Build Coastguard Worker */ 428*54e60f84SAndroid Build Coastguard Worker void *data; 429*54e60f84SAndroid Build Coastguard Worker uint32_t va_reserved[VA_PADDING_LOW]; 430*54e60f84SAndroid Build Coastguard Worker } VAProtectedSessionBuffer; 431*54e60f84SAndroid Build Coastguard Worker 432*54e60f84SAndroid Build Coastguard Worker /** \brief Buffer for vaProtectedSessionExecute() */ 433*54e60f84SAndroid Build Coastguard Worker typedef struct _VAProtectedSessionExecuteBuffer { 434*54e60f84SAndroid Build Coastguard Worker /** \brief Specify the function to execute. It is IHV's implementation 435*54e60f84SAndroid Build Coastguard Worker * specific */ 436*54e60f84SAndroid Build Coastguard Worker uint32_t function_id; 437*54e60f84SAndroid Build Coastguard Worker /** \brief Input buffer */ 438*54e60f84SAndroid Build Coastguard Worker VAProtectedSessionBuffer input; 439*54e60f84SAndroid Build Coastguard Worker /** \brief Output buffer */ 440*54e60f84SAndroid Build Coastguard Worker VAProtectedSessionBuffer output; 441*54e60f84SAndroid Build Coastguard Worker /** \brief Return the result of this function. The status result is IHV's 442*54e60f84SAndroid Build Coastguard Worker * implementation specific */ 443*54e60f84SAndroid Build Coastguard Worker uint32_t status; 444*54e60f84SAndroid Build Coastguard Worker /** \brief - vtag represents TEE sandbox identification for multiple playback scenario 445*54e60f84SAndroid Build Coastguard Worker * 446*54e60f84SAndroid Build Coastguard Worker * If TEE interface is created using VAEntrypointProtectedTEEComm then 447*54e60f84SAndroid Build Coastguard Worker * vtag is non-zero for multiple playback and vtag is zero for single playback 448*54e60f84SAndroid Build Coastguard Worker * 449*54e60f84SAndroid Build Coastguard Worker * If TEE interface is not created using VAEntrypointProtectedTEEComm then 450*54e60f84SAndroid Build Coastguard Worker * vtag - reserved 451*54e60f84SAndroid Build Coastguard Worker */ 452*54e60f84SAndroid Build Coastguard Worker uint64_t vtag; 453*54e60f84SAndroid Build Coastguard Worker /** \brief reserved bytes for future use, must be zero */ 454*54e60f84SAndroid Build Coastguard Worker uint32_t va_reserved[VA_PADDING_LOW - 2]; 455*54e60f84SAndroid Build Coastguard Worker } VAProtectedSessionExecuteBuffer; 456*54e60f84SAndroid Build Coastguard Worker 457*54e60f84SAndroid Build Coastguard Worker /** 458*54e60f84SAndroid Build Coastguard Worker * \brief Create a protected session 459*54e60f84SAndroid Build Coastguard Worker * 460*54e60f84SAndroid Build Coastguard Worker * Create a protected session 461*54e60f84SAndroid Build Coastguard Worker * 462*54e60f84SAndroid Build Coastguard Worker * @param[in] dpy the VA display 463*54e60f84SAndroid Build Coastguard Worker * @param[in] config_id configuration for the protected session 464*54e60f84SAndroid Build Coastguard Worker * @param[out] protected_session created protected session id upon return 465*54e60f84SAndroid Build Coastguard Worker */ 466*54e60f84SAndroid Build Coastguard Worker VAStatus vaCreateProtectedSession(VADisplay dpy, VAConfigID config_id, 467*54e60f84SAndroid Build Coastguard Worker VAProtectedSessionID *protected_session); 468*54e60f84SAndroid Build Coastguard Worker 469*54e60f84SAndroid Build Coastguard Worker /** 470*54e60f84SAndroid Build Coastguard Worker * \brief Destroy a protected session 471*54e60f84SAndroid Build Coastguard Worker * 472*54e60f84SAndroid Build Coastguard Worker * Destroy a protected session 473*54e60f84SAndroid Build Coastguard Worker * 474*54e60f84SAndroid Build Coastguard Worker * @param[in] dpy the VA display 475*54e60f84SAndroid Build Coastguard Worker * @param[in] protected_session protected session to be destroyed 476*54e60f84SAndroid Build Coastguard Worker */ 477*54e60f84SAndroid Build Coastguard Worker VAStatus vaDestroyProtectedSession(VADisplay dpy, 478*54e60f84SAndroid Build Coastguard Worker VAProtectedSessionID protected_session); 479*54e60f84SAndroid Build Coastguard Worker 480*54e60f84SAndroid Build Coastguard Worker /** 481*54e60f84SAndroid Build Coastguard Worker * \brief Attach a protected content session to VA context 482*54e60f84SAndroid Build Coastguard Worker * 483*54e60f84SAndroid Build Coastguard Worker * Attach a protected content session to the context to enable 484*54e60f84SAndroid Build Coastguard Worker * decryption/protection 485*54e60f84SAndroid Build Coastguard Worker * 486*54e60f84SAndroid Build Coastguard Worker * @param[in] dpy the VA display 487*54e60f84SAndroid Build Coastguard Worker * @param[in] id the VA decode/encode/vp context 488*54e60f84SAndroid Build Coastguard Worker * @param[in] protected_session the protected session to attach 489*54e60f84SAndroid Build Coastguard Worker */ 490*54e60f84SAndroid Build Coastguard Worker VAStatus vaAttachProtectedSession(VADisplay dpy, VAGenericID id, 491*54e60f84SAndroid Build Coastguard Worker VAProtectedSessionID protected_session); 492*54e60f84SAndroid Build Coastguard Worker 493*54e60f84SAndroid Build Coastguard Worker /** 494*54e60f84SAndroid Build Coastguard Worker * \brief Detach the protected content session from the VA context 495*54e60f84SAndroid Build Coastguard Worker * 496*54e60f84SAndroid Build Coastguard Worker * Detach protected content session of the context to disable 497*54e60f84SAndroid Build Coastguard Worker * decryption/protection 498*54e60f84SAndroid Build Coastguard Worker * 499*54e60f84SAndroid Build Coastguard Worker * @param[in] dpy the VA display 500*54e60f84SAndroid Build Coastguard Worker * @param[in] id TEE client id to be detached 501*54e60f84SAndroid Build Coastguard Worker */ 502*54e60f84SAndroid Build Coastguard Worker VAStatus vaDetachProtectedSession(VADisplay dpy, VAGenericID id); 503*54e60f84SAndroid Build Coastguard Worker 504*54e60f84SAndroid Build Coastguard Worker /** 505*54e60f84SAndroid Build Coastguard Worker * \brief Execute provides a general mechanism for TEE client tasks execution. 506*54e60f84SAndroid Build Coastguard Worker * 507*54e60f84SAndroid Build Coastguard Worker * vaProtectedSessionExecute provides a mechanism for TEE clients to execute 508*54e60f84SAndroid Build Coastguard Worker * specific tasks. The implementation may differ between IHVs. 509*54e60f84SAndroid Build Coastguard Worker * This is a synchronous API. 510*54e60f84SAndroid Build Coastguard Worker * 511*54e60f84SAndroid Build Coastguard Worker * @param[in] dpy the VA display 512*54e60f84SAndroid Build Coastguard Worker * @param[in] protected_session the protected session 513*54e60f84SAndroid Build Coastguard Worker * @param[in,out] buf_id the VA buffer 514*54e60f84SAndroid Build Coastguard Worker */ 515*54e60f84SAndroid Build Coastguard Worker VAStatus vaProtectedSessionExecute(VADisplay dpy, 516*54e60f84SAndroid Build Coastguard Worker VAProtectedSessionID protected_session, 517*54e60f84SAndroid Build Coastguard Worker VABufferID buf_id); 518*54e60f84SAndroid Build Coastguard Worker 519*54e60f84SAndroid Build Coastguard Worker /**@}*/ 520*54e60f84SAndroid Build Coastguard Worker 521*54e60f84SAndroid Build Coastguard Worker #ifdef __cplusplus 522*54e60f84SAndroid Build Coastguard Worker } 523*54e60f84SAndroid Build Coastguard Worker #endif 524*54e60f84SAndroid Build Coastguard Worker 525*54e60f84SAndroid Build Coastguard Worker #endif /* VA_PROT_H */ 526