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