History

avcodec/avcodec.h: Add encryption info side data.

This new side-data will contain info on how a packet is encrypted. This allows the app to handle packet decryption.

Jacob Trimble committed 8 years ago

Commit db2a7c91 parent 829aebf6 files · +515 −1Browse files

Unified · Split

6 files
  1. doc/APIchanges +4 −0
  2. libavcodec/avcodec.h +13 −0
  3. libavutil/Makefile +2 −0
  4. libavutil/encryption_info.c +295 −0
  5. libavutil/encryption_info.h +200 −0
  6. libavutil/version.h +1 −1
doc/APIchanges+4−0
@@ -15,6 +15,10 @@ libavutil: 2017-10-21 · 14 unmodified lines
1515
1616 API changes, most recent first:
1717
18+2018-xx-xx - xxxxxxx - lavu 56.8.100 - encryption_info.h
19+ Add AVEncryptionInitInfo and AVEncryptionInfo structures to hold new side-data
20+ for encryption info.
21+
1822 2018-03-21 - xxxxxxx - lavc 58.15.100 - avcodec.h
1923 Add av_packet_make_writable().
2024
libavcodec/avcodec.h+13−0
@@ -1344,6 +1344,19 @@ enum AVPacketSideDataType { · 1343 unmodified lines
13441344 */
13451345 AV_PKT_DATA_A53_CC,
13461346
1347+ /**
1348+ * This side data is encryption initialization data.
1349+ * The format is not part of ABI, use av_encryption_init_info_* methods to
1350+ * access.
1351+ */
1352+ AV_PKT_DATA_ENCRYPTION_INIT_INFO,
1353+
1354+ /**
1355+ * This side data contains encryption info for how to decrypt the packet.
1356+ * The format is not part of ABI, use av_encryption_info_* methods to access.
1357+ */
1358+ AV_PKT_DATA_ENCRYPTION_INFO,
1359+
13471360 /**
13481361 * The number of side data types.
13491362 * This is not part of the public API/ABI in the sense that it may
libavutil/Makefile+2−0
@@ -24,6 +24,7 @@ HEADERS = adler32.h \ · 23 unmodified lines
2424 dict.h \
2525 display.h \
2626 downmix_info.h \
27+ encryption_info.h \
2728 error.h \
2829 eval.h \
2930 fifo.h \
@@ -107,6 +108,7 @@ OBJS = adler32.o \ · 77 unmodified lines
107108 dict.o \
108109 display.o \
109110 downmix_info.o \
111+ encryption_info.o \
110112 error.o \
111113 eval.o \
112114 fifo.o \
libavutil/encryption_info.c+295−0
@@ -0,0 +1,295 @@
1+/**
2+ * This file is part of FFmpeg.
3+ *
4+ * FFmpeg is free software; you can redistribute it and/or
5+ * modify it under the terms of the GNU Lesser General Public
6+ * License as published by the Free Software Foundation; either
7+ * version 2.1 of the License, or (at your option) any later version.
8+ *
9+ * FFmpeg is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+ * Lesser General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU Lesser General Public
15+ * License along with FFmpeg; if not, write to the Free Software
16+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17+ */
18+
19+#include "encryption_info.h"
20+#include "mem.h"
21+#include "intreadwrite.h"
22+
23+#define FF_ENCRYPTION_INFO_EXTRA 24
24+
25+// The format of the AVEncryptionInfo side data:
26+// u32be scheme
27+// u32be crypt_byte_block
28+// u32be skip_byte_block
29+// u32be key_id_size
30+// u32be iv_size
31+// u32be subsample_count
32+// u8[key_id_size] key_id
33+// u8[iv_size] iv
34+// {
35+// u32be bytes_of_clear_data
36+// u32be bytes_of_protected_data
37+// }[subsample_count]
38+
39+AVEncryptionInfo *av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size)
40+{
41+ AVEncryptionInfo *info;
42+
43+ info = av_mallocz(sizeof(*info));
44+ if (!info)
45+ return NULL;
46+
47+ info->key_id = av_mallocz(key_id_size);
48+ info->key_id_size = key_id_size;
49+ info->iv = av_mallocz(iv_size);
50+ info->iv_size = iv_size;
51+ info->subsamples = av_mallocz_array(subsample_count, sizeof(*info->subsamples));
52+ info->subsample_count = subsample_count;
53+
54+ // Allow info->subsamples to be NULL if there are no subsamples.
55+ if (!info->key_id || !info->iv || (!info->subsamples && subsample_count)) {
56+ av_encryption_info_free(info);
57+ return NULL;
58+ }
59+
60+ return info;
61+}
62+
63+AVEncryptionInfo *av_encryption_info_clone(const AVEncryptionInfo *info)
64+{
65+ AVEncryptionInfo *ret;
66+
67+ ret = av_encryption_info_alloc(info->subsample_count, info->key_id_size, info->iv_size);
68+ if (!ret)
69+ return NULL;
70+
71+ ret->scheme = info->scheme;
72+ ret->crypt_byte_block = info->crypt_byte_block;
73+ ret->skip_byte_block = info->skip_byte_block;
74+ memcpy(ret->iv, info->iv, info->iv_size);
75+ memcpy(ret->key_id, info->key_id, info->key_id_size);
76+ memcpy(ret->subsamples, info->subsamples, sizeof(*info->subsamples) * info->subsample_count);
77+ return ret;
78+}
79+
80+void av_encryption_info_free(AVEncryptionInfo *info)
81+{
82+ if (info) {
83+ av_free(info->key_id);
84+ av_free(info->iv);
85+ av_free(info->subsamples);
86+ av_free(info);
87+ }
88+}
89+
90+AVEncryptionInfo *av_encryption_info_get_side_data(const uint8_t* buffer, size_t size)
91+{
92+ AVEncryptionInfo *info;
93+ uint64_t key_id_size, iv_size, subsample_count, i;
94+
95+ if (!buffer || size < FF_ENCRYPTION_INFO_EXTRA)
96+ return NULL;
97+
98+ key_id_size = AV_RB32(buffer + 12);
99+ iv_size = AV_RB32(buffer + 16);
100+ subsample_count = AV_RB32(buffer + 20);
101+
102+ if (size < FF_ENCRYPTION_INFO_EXTRA + key_id_size + iv_size + subsample_count * 8)
103+ return NULL;
104+
105+ info = av_encryption_info_alloc(subsample_count, key_id_size, iv_size);
106+ if (!info)
107+ return NULL;
108+
109+ info->scheme = AV_RB32(buffer);
110+ info->crypt_byte_block = AV_RB32(buffer + 4);
111+ info->skip_byte_block = AV_RB32(buffer + 8);
112+ memcpy(info->key_id, buffer + 24, key_id_size);
113+ memcpy(info->iv, buffer + key_id_size + 24, iv_size);
114+
115+ buffer += key_id_size + iv_size + 24;
116+ for (i = 0; i < subsample_count; i++) {
117+ info->subsamples[i].bytes_of_clear_data = AV_RB32(buffer);
118+ info->subsamples[i].bytes_of_protected_data = AV_RB32(buffer + 4);
119+ buffer += 8;
120+ }
121+
122+ return info;
123+}
124+
125+uint8_t *av_encryption_info_add_side_data(const AVEncryptionInfo *info, size_t *size)
126+{
127+ uint8_t *buffer, *cur_buffer;
128+ uint32_t i;
129+
130+ if (UINT32_MAX - FF_ENCRYPTION_INFO_EXTRA < info->key_id_size ||
131+ UINT32_MAX - FF_ENCRYPTION_INFO_EXTRA - info->key_id_size < info->iv_size ||
132+ (UINT32_MAX - FF_ENCRYPTION_INFO_EXTRA - info->key_id_size - info->iv_size) / 8 < info->subsample_count) {
133+ return NULL;
134+ }
135+
136+ *size = FF_ENCRYPTION_INFO_EXTRA + info->key_id_size + info->iv_size +
137+ (info->subsample_count * 8);
138+ cur_buffer = buffer = av_malloc(*size);
139+ if (!buffer)
140+ return NULL;
141+
142+ AV_WB32(cur_buffer, info->scheme);
143+ AV_WB32(cur_buffer + 4, info->crypt_byte_block);
144+ AV_WB32(cur_buffer + 8, info->skip_byte_block);
145+ AV_WB32(cur_buffer + 12, info->key_id_size);
146+ AV_WB32(cur_buffer + 16, info->iv_size);
147+ AV_WB32(cur_buffer + 20, info->subsample_count);
148+ cur_buffer += 24;
149+ memcpy(cur_buffer, info->key_id, info->key_id_size);
150+ cur_buffer += info->key_id_size;
151+ memcpy(cur_buffer, info->iv, info->iv_size);
152+ cur_buffer += info->iv_size;
153+ for (i = 0; i < info->subsample_count; i++) {
154+ AV_WB32(cur_buffer, info->subsamples[i].bytes_of_clear_data);
155+ AV_WB32(cur_buffer + 4, info->subsamples[i].bytes_of_protected_data);
156+ cur_buffer += 8;
157+ }
158+
159+ return buffer;
160+}
161+
162+// The format of the AVEncryptionInitInfo side data:
163+// u32be system_id_size
164+// u32be num_key_ids
165+// u32be key_id_size
166+// u32be data_size
167+// u8[system_id_size] system_id
168+// u8[key_id_size][num_key_id] key_ids
169+// u8[data_size] data
170+
171+#define FF_ENCRYPTION_INIT_INFO_EXTRA 16
172+
173+AVEncryptionInitInfo *av_encryption_init_info_alloc(
174+ uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
175+{
176+ AVEncryptionInitInfo *info;
177+ uint32_t i;
178+
179+ info = av_mallocz(sizeof(*info));
180+ if (!info)
181+ return NULL;
182+
183+ info->system_id = av_mallocz(system_id_size);
184+ info->system_id_size = system_id_size;
185+ info->key_ids = key_id_size ? av_mallocz_array(num_key_ids, sizeof(*info->key_ids)) : NULL;
186+ info->num_key_ids = num_key_ids;
187+ info->key_id_size = key_id_size;
188+ info->data = av_mallocz(data_size);
189+ info->data_size = data_size;
190+
191+ // Allow pointers to be NULL if the size is 0.
192+ if ((!info->system_id && system_id_size) || (!info->data && data_size) ||
193+ (!info->key_ids && num_key_ids && key_id_size)) {
194+ av_encryption_init_info_free(info);
195+ return NULL;
196+ }
197+
198+ if (key_id_size) {
199+ for (i = 0; i < num_key_ids; i++) {
200+ info->key_ids[i] = av_mallocz(key_id_size);
201+ if (!info->key_ids[i]) {
202+ av_encryption_init_info_free(info);
203+ return NULL;
204+ }
205+ }
206+ }
207+
208+ return info;
209+}
210+
211+void av_encryption_init_info_free(AVEncryptionInitInfo *info)
212+{
213+ uint32_t i;
214+ if (info) {
215+ for (i = 0; i < info->num_key_ids; i++) {
216+ av_free(info->key_ids[i]);
217+ }
218+ av_free(info->system_id);
219+ av_free(info->key_ids);
220+ av_free(info->data);
221+ av_free(info);
222+ }
223+}
224+
225+AVEncryptionInitInfo *av_encryption_init_info_get_side_data(
226+ const uint8_t *side_data, size_t side_data_size)
227+{
228+ AVEncryptionInitInfo *info;
229+ uint64_t system_id_size, num_key_ids, key_id_size, data_size, i;
230+
231+ if (!side_data || side_data_size < FF_ENCRYPTION_INIT_INFO_EXTRA)
232+ return NULL;
233+
234+ system_id_size = AV_RB32(side_data);
235+ num_key_ids = AV_RB32(side_data + 4);
236+ key_id_size = AV_RB32(side_data + 8);
237+ data_size = AV_RB32(side_data + 12);
238+
239+ // UINT32_MAX + UINT32_MAX + UINT32_MAX * UINT32_MAX == UINT64_MAX
240+ if (side_data_size - FF_ENCRYPTION_INIT_INFO_EXTRA < system_id_size + data_size + num_key_ids * key_id_size)
241+ return NULL;
242+
243+ info = av_encryption_init_info_alloc(system_id_size, num_key_ids, key_id_size, data_size);
244+ if (!info)
245+ return NULL;
246+
247+ memcpy(info->system_id, side_data + 16, system_id_size);
248+ side_data += system_id_size + 16;
249+ for (i = 0; i < num_key_ids; i++) {
250+ memcpy(info->key_ids[i], side_data, key_id_size);
251+ side_data += key_id_size;
252+ }
253+ memcpy(info->data, side_data, data_size);
254+
255+ return info;
256+}
257+
258+uint8_t *av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
259+{
260+ uint8_t *buffer, *cur_buffer;
261+ uint32_t i, max_size;
262+
263+ if (UINT32_MAX - FF_ENCRYPTION_INIT_INFO_EXTRA < info->system_id_size ||
264+ UINT32_MAX - FF_ENCRYPTION_INIT_INFO_EXTRA - info->system_id_size < info->data_size) {
265+ return NULL;
266+ }
267+
268+ if (info->num_key_ids) {
269+ max_size = UINT32_MAX - FF_ENCRYPTION_INIT_INFO_EXTRA - info->system_id_size - info->data_size;
270+ if (max_size / info->num_key_ids < info->key_id_size)
271+ return NULL;
272+ }
273+
274+ *side_data_size = FF_ENCRYPTION_INIT_INFO_EXTRA + info->system_id_size +
275+ info->data_size + (info->num_key_ids * info->key_id_size);
276+ cur_buffer = buffer = av_malloc(*side_data_size);
277+ if (!buffer)
278+ return NULL;
279+
280+ AV_WB32(cur_buffer, info->system_id_size);
281+ AV_WB32(cur_buffer + 4, info->num_key_ids);
282+ AV_WB32(cur_buffer + 8, info->key_id_size);
283+ AV_WB32(cur_buffer + 12, info->data_size);
284+ cur_buffer += 16;
285+
286+ memcpy(cur_buffer, info->system_id, info->system_id_size);
287+ cur_buffer += info->system_id_size;
288+ for (i = 0; i < info->num_key_ids; i++) {
289+ memcpy(cur_buffer, info->key_ids[i], info->key_id_size);
290+ cur_buffer += info->key_id_size;
291+ }
292+ memcpy(cur_buffer, info->data, info->data_size);
293+
294+ return buffer;
295+}
libavutil/encryption_info.h+200−0
@@ -0,0 +1,200 @@
1+/**
2+ * This file is part of FFmpeg.
3+ *
4+ * FFmpeg is free software; you can redistribute it and/or
5+ * modify it under the terms of the GNU Lesser General Public
6+ * License as published by the Free Software Foundation; either
7+ * version 2.1 of the License, or (at your option) any later version.
8+ *
9+ * FFmpeg is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+ * Lesser General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU Lesser General Public
15+ * License along with FFmpeg; if not, write to the Free Software
16+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17+ */
18+
19+#ifndef AVUTIL_ENCRYPTION_INFO_H
20+#define AVUTIL_ENCRYPTION_INFO_H
21+
22+#include <stddef.h>
23+#include <stdint.h>
24+
25+typedef struct AVSubsampleEncryptionInfo {
26+ /** The number of bytes that are clear. */
27+ unsigned int bytes_of_clear_data;
28+
29+ /**
30+ * The number of bytes that are protected. If using pattern encryption,
31+ * the pattern applies to only the protected bytes; if not using pattern
32+ * encryption, all these bytes are encrypted.
33+ */
34+ unsigned int bytes_of_protected_data;
35+} AVSubsampleEncryptionInfo;
36+
37+/**
38+ * This describes encryption info for a packet. This contains frame-specific
39+ * info for how to decrypt the packet before passing it to the decoder.
40+ *
41+ * The size of this struct is not part of the public ABI.
42+ */
43+typedef struct AVEncryptionInfo {
44+ /** The fourcc encryption scheme. */
45+ uint32_t scheme;
46+
47+ /**
48+ * Only used for pattern encryption. This is the number of 16-byte blocks
49+ * that are encrypted.
50+ */
51+ uint32_t crypt_byte_block;
52+
53+ /**
54+ * Only used for pattern encryption. This is the number of 16-byte blocks
55+ * that are clear.
56+ */
57+ uint32_t skip_byte_block;
58+
59+ /**
60+ * The ID of the key used to encrypt the packet. This should always be
61+ * 16 bytes long, but may be changed in the future.
62+ */
63+ uint8_t *key_id;
64+ uint32_t key_id_size;
65+
66+ /**
67+ * The initialization vector. This may have been zero-filled to be the
68+ * correct block size. This should always be 16 bytes long, but may be
69+ * changed in the future.
70+ */
71+ uint8_t *iv;
72+ uint32_t iv_size;
73+
74+ /**
75+ * An array of subsample encryption info specifying how parts of the sample
76+ * are encrypted. If there are no subsamples, then the whole sample is
77+ * encrypted.
78+ */
79+ AVSubsampleEncryptionInfo *subsamples;
80+ uint32_t subsample_count;
81+} AVEncryptionInfo;
82+
83+/**
84+ * This describes info used to initialize an encryption key system.
85+ *
86+ * The size of this struct is not part of the public ABI.
87+ */
88+typedef struct AVEncryptionInitInfo {
89+ /**
90+ * A unique identifier for the key system this is for, can be NULL if it
91+ * is not known. This should always be 16 bytes, but may change in the
92+ * future.
93+ */
94+ uint8_t* system_id;
95+ uint32_t system_id_size;
96+
97+ /**
98+ * An array of key IDs this initialization data is for. All IDs are the
99+ * same length. Can be NULL if there are no known key IDs.
100+ */
101+ uint8_t** key_ids;
102+ /** The number of key IDs. */
103+ uint32_t num_key_ids;
104+ /**
105+ * The number of bytes in each key ID. This should always be 16, but may
106+ * change in the future.
107+ */
108+ uint32_t key_id_size;
109+
110+ /**
111+ * Key-system specific initialization data. This data is copied directly
112+ * from the file and the format depends on the specific key system. This
113+ * can be NULL if there is no initialization data; in that case, there
114+ * will be at least one key ID.
115+ */
116+ uint8_t* data;
117+ uint32_t data_size;
118+} AVEncryptionInitInfo;
119+
120+/**
121+ * Allocates an AVEncryptionInfo structure and sub-pointers to hold the given
122+ * number of subsamples. This will allocate pointers for the key ID, IV,
123+ * and subsample entries, set the size members, and zero-initialize the rest.
124+ *
125+ * @param subsample_count The number of subsamples.
126+ * @param key_id_size The number of bytes in the key ID, should be 16.
127+ * @param key_id_size The number of bytes in the IV, should be 16.
128+ *
129+ * @return The new AVEncryptionInfo structure, or NULL on error.
130+ */
131+AVEncryptionInfo *av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size);
132+
133+/**
134+ * Allocates an AVEncryptionInfo structure with a copy of the given data.
135+ * @return The new AVEncryptionInfo structure, or NULL on error.
136+ */
137+AVEncryptionInfo *av_encryption_info_clone(const AVEncryptionInfo *info);
138+
139+/**
140+ * Frees the given encryption info object. This MUST NOT be used to free the
141+ * side-data data pointer, that should use normal side-data methods.
142+ */
143+void av_encryption_info_free(AVEncryptionInfo *info);
144+
145+/**
146+ * Creates a copy of the AVEncryptionInfo that is contained in the given side
147+ * data. The resulting object should be passed to av_encryption_info_free()
148+ * when done.
149+ *
150+ * @return The new AVEncryptionInfo structure, or NULL on error.
151+ */
152+AVEncryptionInfo *av_encryption_info_get_side_data(const uint8_t *side_data, size_t side_data_size);
153+
154+/**
155+ * Allocates and initializes side data that holds a copy of the given encryption
156+ * info. The resulting pointer should be either freed using av_free or given
157+ * to av_packet_add_side_data().
158+ *
159+ * @return The new side-data pointer, or NULL.
160+ */
161+uint8_t *av_encryption_info_add_side_data(
162+ const AVEncryptionInfo *info, size_t *side_data_size);
163+
164+
165+/**
166+ * Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the
167+ * given sizes. This will allocate pointers and set all the fields.
168+ *
169+ * @return The new AVEncryptionInitInfo structure, or NULL on error.
170+ */
171+AVEncryptionInitInfo *av_encryption_init_info_alloc(
172+ uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size);
173+
174+/**
175+ * Frees the given encryption init info object. This MUST NOT be used to free
176+ * the side-data data pointer, that should use normal side-data methods.
177+ */
178+void av_encryption_init_info_free(AVEncryptionInitInfo* info);
179+
180+/**
181+ * Creates a copy of the AVEncryptionInitInfo that is contained in the given
182+ * side data. The resulting object should be passed to
183+ * av_encryption_init_info_free() when done.
184+ *
185+ * @return The new AVEncryptionInitInfo structure, or NULL on error.
186+ */
187+AVEncryptionInitInfo *av_encryption_init_info_get_side_data(
188+ const uint8_t* side_data, size_t side_data_size);
189+
190+/**
191+ * Allocates and initializes side data that holds a copy of the given encryption
192+ * init info. The resulting pointer should be either freed using av_free or
193+ * given to av_packet_add_side_data().
194+ *
195+ * @return The new side-data pointer, or NULL.
196+ */
197+uint8_t *av_encryption_init_info_add_side_data(
198+ const AVEncryptionInitInfo *info, size_t *side_data_size);
199+
200+#endif /* AVUTIL_ENCRYPTION_INFO_H */
libavutil/version.h+1−1
@@ -79,7 +79,7 @@ · 78 unmodified lines
7979 */
8080
8181 #define LIBAVUTIL_VERSION_MAJOR 56
82−#define LIBAVUTIL_VERSION_MINOR 11
82+#define LIBAVUTIL_VERSION_MINOR 12
8383 #define LIBAVUTIL_VERSION_MICRO 100
8484
8585 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t