FFmpeg
encryption_info.c
Go to the documentation of this file.
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 <string.h>
20 
21 #include "encryption_info.h"
22 #include "mem.h"
23 #include "intreadwrite.h"
24 
25 #define FF_ENCRYPTION_INFO_EXTRA 24
26 
27 // The format of the AVEncryptionInfo side data:
28 // u32be scheme
29 // u32be crypt_byte_block
30 // u32be skip_byte_block
31 // u32be key_id_size
32 // u32be iv_size
33 // u32be subsample_count
34 // u8[key_id_size] key_id
35 // u8[iv_size] iv
36 // {
37 // u32be bytes_of_clear_data
38 // u32be bytes_of_protected_data
39 // }[subsample_count]
40 
41 AVEncryptionInfo *av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size)
42 {
44 
45  info = av_mallocz(sizeof(*info));
46  if (!info)
47  return NULL;
48 
49  info->key_id = av_mallocz(key_id_size);
50  info->key_id_size = key_id_size;
51  info->iv = av_mallocz(iv_size);
52  info->iv_size = iv_size;
53  info->subsamples = av_calloc(subsample_count, sizeof(*info->subsamples));
54  info->subsample_count = subsample_count;
55 
56  // Allow info->subsamples to be NULL if there are no subsamples.
57  if (!info->key_id || !info->iv || (!info->subsamples && subsample_count)) {
59  return NULL;
60  }
61 
62  return info;
63 }
64 
66 {
68 
69  ret = av_encryption_info_alloc(info->subsample_count, info->key_id_size, info->iv_size);
70  if (!ret)
71  return NULL;
72 
73  ret->scheme = info->scheme;
74  ret->crypt_byte_block = info->crypt_byte_block;
75  ret->skip_byte_block = info->skip_byte_block;
76  memcpy(ret->iv, info->iv, info->iv_size);
77  memcpy(ret->key_id, info->key_id, info->key_id_size);
78  memcpy(ret->subsamples, info->subsamples, sizeof(*info->subsamples) * info->subsample_count);
79  return ret;
80 }
81 
83 {
84  if (info) {
85  av_free(info->key_id);
86  av_free(info->iv);
87  av_free(info->subsamples);
88  av_free(info);
89  }
90 }
91 
93 {
95  uint64_t key_id_size, iv_size, subsample_count, i;
96 
98  return NULL;
99 
100  key_id_size = AV_RB32(buffer + 12);
101  iv_size = AV_RB32(buffer + 16);
102  subsample_count = AV_RB32(buffer + 20);
103 
104  if (size < FF_ENCRYPTION_INFO_EXTRA + key_id_size + iv_size + subsample_count * 8)
105  return NULL;
106 
107  info = av_encryption_info_alloc(subsample_count, key_id_size, iv_size);
108  if (!info)
109  return NULL;
110 
111  info->scheme = AV_RB32(buffer);
112  info->crypt_byte_block = AV_RB32(buffer + 4);
113  info->skip_byte_block = AV_RB32(buffer + 8);
114  memcpy(info->key_id, buffer + 24, key_id_size);
115  memcpy(info->iv, buffer + key_id_size + 24, iv_size);
116 
117  buffer += key_id_size + iv_size + 24;
118  for (i = 0; i < subsample_count; i++) {
119  info->subsamples[i].bytes_of_clear_data = AV_RB32(buffer);
120  info->subsamples[i].bytes_of_protected_data = AV_RB32(buffer + 4);
121  buffer += 8;
122  }
123 
124  return info;
125 }
126 
128 {
129  uint8_t *buffer, *cur_buffer;
130  uint32_t i;
131 
132  if (UINT32_MAX - FF_ENCRYPTION_INFO_EXTRA < info->key_id_size ||
133  UINT32_MAX - FF_ENCRYPTION_INFO_EXTRA - info->key_id_size < info->iv_size ||
134  (UINT32_MAX - FF_ENCRYPTION_INFO_EXTRA - info->key_id_size - info->iv_size) / 8 < info->subsample_count) {
135  return NULL;
136  }
137 
138  *size = FF_ENCRYPTION_INFO_EXTRA + info->key_id_size + info->iv_size +
139  (info->subsample_count * 8);
140  cur_buffer = buffer = av_malloc(*size);
141  if (!buffer)
142  return NULL;
143 
144  AV_WB32(cur_buffer, info->scheme);
145  AV_WB32(cur_buffer + 4, info->crypt_byte_block);
146  AV_WB32(cur_buffer + 8, info->skip_byte_block);
147  AV_WB32(cur_buffer + 12, info->key_id_size);
148  AV_WB32(cur_buffer + 16, info->iv_size);
149  AV_WB32(cur_buffer + 20, info->subsample_count);
150  cur_buffer += 24;
151  memcpy(cur_buffer, info->key_id, info->key_id_size);
152  cur_buffer += info->key_id_size;
153  memcpy(cur_buffer, info->iv, info->iv_size);
154  cur_buffer += info->iv_size;
155  for (i = 0; i < info->subsample_count; i++) {
156  AV_WB32(cur_buffer, info->subsamples[i].bytes_of_clear_data);
157  AV_WB32(cur_buffer + 4, info->subsamples[i].bytes_of_protected_data);
158  cur_buffer += 8;
159  }
160 
161  return buffer;
162 }
163 
164 // The format of the AVEncryptionInitInfo side data:
165 // u32be init_info_count
166 // {
167 // u32be system_id_size
168 // u32be num_key_ids
169 // u32be key_id_size
170 // u32be data_size
171 // u8[system_id_size] system_id
172 // u8[key_id_size][num_key_id] key_ids
173 // u8[data_size] data
174 // }[init_info_count]
175 
176 #define FF_ENCRYPTION_INIT_INFO_EXTRA 16
177 
179  uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
180 {
182  uint32_t i;
183 
184  info = av_mallocz(sizeof(*info));
185  if (!info)
186  return NULL;
187 
188  info->system_id = av_mallocz(system_id_size);
189  info->system_id_size = system_id_size;
190  info->key_ids = key_id_size ? av_calloc(num_key_ids, sizeof(*info->key_ids)) : NULL;
191  info->num_key_ids = num_key_ids;
192  info->key_id_size = key_id_size;
193  info->data = av_mallocz(data_size);
194  info->data_size = data_size;
195 
196  // Allow pointers to be NULL if the size is 0.
197  if ((!info->system_id && system_id_size) || (!info->data && data_size) ||
198  (!info->key_ids && num_key_ids && key_id_size)) {
200  return NULL;
201  }
202 
203  if (key_id_size) {
204  for (i = 0; i < num_key_ids; i++) {
205  info->key_ids[i] = av_mallocz(key_id_size);
206  if (!info->key_ids[i]) {
208  return NULL;
209  }
210  }
211  }
212 
213  return info;
214 }
215 
217 {
218  uint32_t i;
219  if (info) {
220  for (i = 0; i < info->num_key_ids; i++) {
221  av_free(info->key_ids[i]);
222  }
224  av_free(info->system_id);
225  av_free(info->key_ids);
226  av_free(info->data);
227  av_free(info);
228  }
229 }
230 
232  const uint8_t *side_data, size_t side_data_size)
233 {
234  // |ret| tracks the front of the list, |info| tracks the back.
235  AVEncryptionInitInfo *ret = NULL, *info, *temp_info;
236  uint64_t system_id_size, num_key_ids, key_id_size, data_size, i, j;
237  uint64_t init_info_count;
238 
239  if (!side_data || side_data_size < 4)
240  return NULL;
241 
242  init_info_count = AV_RB32(side_data);
243  side_data += 4;
244  side_data_size -= 4;
245  for (i = 0; i < init_info_count; i++) {
246  if (side_data_size < FF_ENCRYPTION_INIT_INFO_EXTRA) {
248  return NULL;
249  }
250 
251  system_id_size = AV_RB32(side_data);
252  num_key_ids = AV_RB32(side_data + 4);
253  key_id_size = AV_RB32(side_data + 8);
254  data_size = AV_RB32(side_data + 12);
255 
256  // UINT32_MAX + UINT32_MAX + UINT32_MAX * UINT32_MAX == UINT64_MAX
257  if (side_data_size - FF_ENCRYPTION_INIT_INFO_EXTRA < system_id_size + data_size + num_key_ids * key_id_size) {
259  return NULL;
260  }
261  side_data += FF_ENCRYPTION_INIT_INFO_EXTRA;
262  side_data_size -= FF_ENCRYPTION_INIT_INFO_EXTRA;
263 
264  temp_info = av_encryption_init_info_alloc(system_id_size, num_key_ids, key_id_size, data_size);
265  if (!temp_info) {
267  return NULL;
268  }
269  if (i == 0) {
270  info = ret = temp_info;
271  } else {
272  info->next = temp_info;
273  info = temp_info;
274  }
275 
276  memcpy(info->system_id, side_data, system_id_size);
277  side_data += system_id_size;
278  side_data_size -= system_id_size;
279  for (j = 0; j < num_key_ids; j++) {
280  memcpy(info->key_ids[j], side_data, key_id_size);
281  side_data += key_id_size;
282  side_data_size -= key_id_size;
283  }
284  memcpy(info->data, side_data, data_size);
285  side_data += data_size;
286  side_data_size -= data_size;
287  }
288 
289  return ret;
290 }
291 
292 uint8_t *av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
293 {
294  const AVEncryptionInitInfo *cur_info;
295  uint8_t *buffer, *cur_buffer;
296  uint32_t i, init_info_count;
297  uint64_t temp_side_data_size;
298 
299  temp_side_data_size = 4;
300  init_info_count = 0;
301  for (cur_info = info; cur_info; cur_info = cur_info->next) {
302  temp_side_data_size += (uint64_t)FF_ENCRYPTION_INIT_INFO_EXTRA + cur_info->system_id_size + cur_info->data_size;
303  if (init_info_count == UINT32_MAX || temp_side_data_size > UINT32_MAX) {
304  return NULL;
305  }
306  init_info_count++;
307 
308  if (cur_info->num_key_ids) {
309  temp_side_data_size += (uint64_t)cur_info->num_key_ids * cur_info->key_id_size;
310  if (temp_side_data_size > UINT32_MAX) {
311  return NULL;
312  }
313  }
314  }
315  *side_data_size = temp_side_data_size;
316 
317  cur_buffer = buffer = av_malloc(*side_data_size);
318  if (!buffer)
319  return NULL;
320 
321  AV_WB32(cur_buffer, init_info_count);
322  cur_buffer += 4;
323  for (cur_info = info; cur_info; cur_info = cur_info->next) {
324  AV_WB32(cur_buffer, cur_info->system_id_size);
325  AV_WB32(cur_buffer + 4, cur_info->num_key_ids);
326  AV_WB32(cur_buffer + 8, cur_info->key_id_size);
327  AV_WB32(cur_buffer + 12, cur_info->data_size);
328  cur_buffer += 16;
329 
330  memcpy(cur_buffer, cur_info->system_id, cur_info->system_id_size);
331  cur_buffer += cur_info->system_id_size;
332  for (i = 0; i < cur_info->num_key_ids; i++) {
333  memcpy(cur_buffer, cur_info->key_ids[i], cur_info->key_id_size);
334  cur_buffer += cur_info->key_id_size;
335  }
336  if (cur_info->data_size > 0) {
337  memcpy(cur_buffer, cur_info->data, cur_info->data_size);
338  cur_buffer += cur_info->data_size;
339  }
340  }
341 
342  return buffer;
343 }
av_encryption_info_get_side_data
AVEncryptionInfo * av_encryption_info_get_side_data(const uint8_t *buffer, size_t size)
Creates a copy of the AVEncryptionInfo that is contained in the given side data.
Definition: encryption_info.c:92
FF_ENCRYPTION_INIT_INFO_EXTRA
#define FF_ENCRYPTION_INIT_INFO_EXTRA
Definition: encryption_info.c:176
av_encryption_init_info_free
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
Definition: encryption_info.c:216
av_encryption_init_info_get_side_data
AVEncryptionInitInfo * av_encryption_init_info_get_side_data(const uint8_t *side_data, size_t side_data_size)
Creates a copy of the AVEncryptionInitInfo that is contained in the given side data.
Definition: encryption_info.c:231
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
AVEncryptionInitInfo::data_size
uint32_t data_size
Definition: encryption_info.h:117
AVEncryptionInitInfo::key_id_size
uint32_t key_id_size
The number of bytes in each key ID.
Definition: encryption_info.h:108
av_encryption_info_clone
AVEncryptionInfo * av_encryption_info_clone(const AVEncryptionInfo *info)
Allocates an AVEncryptionInfo structure with a copy of the given data.
Definition: encryption_info.c:65
intreadwrite.h
info
MIPS optimizations info
Definition: mips.txt:2
if
if(ret)
Definition: filter_design.txt:179
NULL
#define NULL
Definition: coverity.c:32
AVEncryptionInitInfo
This describes info used to initialize an encryption key system.
Definition: encryption_info.h:88
AVEncryptionInitInfo::system_id
uint8_t * system_id
A unique identifier for the key system this is for, can be NULL if it is not known.
Definition: encryption_info.h:94
FF_ENCRYPTION_INFO_EXTRA
#define FF_ENCRYPTION_INFO_EXTRA
This file is part of FFmpeg.
Definition: encryption_info.c:25
av_encryption_info_add_side_data
uint8_t * av_encryption_info_add_side_data(const AVEncryptionInfo *info, size_t *size)
Allocates and initializes side data that holds a copy of the given encryption info.
Definition: encryption_info.c:127
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:417
AVEncryptionInitInfo::num_key_ids
uint32_t num_key_ids
The number of key IDs.
Definition: encryption_info.h:103
size
int size
Definition: twinvq_data.h:10344
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
av_encryption_info_free
void av_encryption_info_free(AVEncryptionInfo *info)
Frees the given encryption info object.
Definition: encryption_info.c:82
AVEncryptionInitInfo::next
struct AVEncryptionInitInfo * next
An optional pointer to the next initialization info in the list.
Definition: encryption_info.h:122
av_encryption_init_info_alloc
AVEncryptionInitInfo * av_encryption_init_info_alloc(uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the given sizes.
Definition: encryption_info.c:178
AVEncryptionInitInfo::key_ids
uint8_t ** key_ids
An array of key IDs this initialization data is for.
Definition: encryption_info.h:101
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:254
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
ret
ret
Definition: filter_design.txt:187
AVEncryptionInitInfo::data
uint8_t * data
Key-system specific initialization data.
Definition: encryption_info.h:116
AVEncryptionInfo
This describes encryption info for a packet.
Definition: encryption_info.h:43
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
encryption_info.h
mem.h
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVEncryptionInitInfo::system_id_size
uint32_t system_id_size
Definition: encryption_info.h:95
av_encryption_info_alloc
AVEncryptionInfo * av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size)
Allocates an AVEncryptionInfo structure and sub-pointers to hold the given number of subsamples.
Definition: encryption_info.c:41
av_encryption_init_info_add_side_data
uint8_t * av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
Allocates and initializes side data that holds a copy of the given encryption init info.
Definition: encryption_info.c:292