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 "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 {
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_calloc(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)) {
57  return NULL;
58  }
59 
60  return info;
61 }
62 
64 {
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 
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 
91 {
93  uint64_t key_id_size, iv_size, subsample_count, i;
94 
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 
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 init_info_count
164 // {
165 // u32be system_id_size
166 // u32be num_key_ids
167 // u32be key_id_size
168 // u32be data_size
169 // u8[system_id_size] system_id
170 // u8[key_id_size][num_key_id] key_ids
171 // u8[data_size] data
172 // }[init_info_count]
173 
174 #define FF_ENCRYPTION_INIT_INFO_EXTRA 16
175 
177  uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
178 {
180  uint32_t i;
181 
182  info = av_mallocz(sizeof(*info));
183  if (!info)
184  return NULL;
185 
186  info->system_id = av_mallocz(system_id_size);
187  info->system_id_size = system_id_size;
188  info->key_ids = key_id_size ? av_calloc(num_key_ids, sizeof(*info->key_ids)) : NULL;
189  info->num_key_ids = num_key_ids;
190  info->key_id_size = key_id_size;
191  info->data = av_mallocz(data_size);
192  info->data_size = data_size;
193 
194  // Allow pointers to be NULL if the size is 0.
195  if ((!info->system_id && system_id_size) || (!info->data && data_size) ||
196  (!info->key_ids && num_key_ids && key_id_size)) {
198  return NULL;
199  }
200 
201  if (key_id_size) {
202  for (i = 0; i < num_key_ids; i++) {
203  info->key_ids[i] = av_mallocz(key_id_size);
204  if (!info->key_ids[i]) {
206  return NULL;
207  }
208  }
209  }
210 
211  return info;
212 }
213 
215 {
216  uint32_t i;
217  if (info) {
218  for (i = 0; i < info->num_key_ids; i++) {
219  av_free(info->key_ids[i]);
220  }
222  av_free(info->system_id);
223  av_free(info->key_ids);
224  av_free(info->data);
225  av_free(info);
226  }
227 }
228 
230  const uint8_t *side_data, size_t side_data_size)
231 {
232  // |ret| tracks the front of the list, |info| tracks the back.
233  AVEncryptionInitInfo *ret = NULL, *info, *temp_info;
234  uint64_t system_id_size, num_key_ids, key_id_size, data_size, i, j;
235  uint64_t init_info_count;
236 
237  if (!side_data || side_data_size < 4)
238  return NULL;
239 
240  init_info_count = AV_RB32(side_data);
241  side_data += 4;
242  side_data_size -= 4;
243  for (i = 0; i < init_info_count; i++) {
244  if (side_data_size < FF_ENCRYPTION_INIT_INFO_EXTRA) {
246  return NULL;
247  }
248 
249  system_id_size = AV_RB32(side_data);
250  num_key_ids = AV_RB32(side_data + 4);
251  key_id_size = AV_RB32(side_data + 8);
252  data_size = AV_RB32(side_data + 12);
253 
254  // UINT32_MAX + UINT32_MAX + UINT32_MAX * UINT32_MAX == UINT64_MAX
255  if (side_data_size - FF_ENCRYPTION_INIT_INFO_EXTRA < system_id_size + data_size + num_key_ids * key_id_size) {
257  return NULL;
258  }
259  side_data += FF_ENCRYPTION_INIT_INFO_EXTRA;
260  side_data_size -= FF_ENCRYPTION_INIT_INFO_EXTRA;
261 
262  temp_info = av_encryption_init_info_alloc(system_id_size, num_key_ids, key_id_size, data_size);
263  if (!temp_info) {
265  return NULL;
266  }
267  if (i == 0) {
268  info = ret = temp_info;
269  } else {
270  info->next = temp_info;
271  info = temp_info;
272  }
273 
274  memcpy(info->system_id, side_data, system_id_size);
275  side_data += system_id_size;
276  side_data_size -= system_id_size;
277  for (j = 0; j < num_key_ids; j++) {
278  memcpy(info->key_ids[j], side_data, key_id_size);
279  side_data += key_id_size;
280  side_data_size -= key_id_size;
281  }
282  memcpy(info->data, side_data, data_size);
283  side_data += data_size;
284  side_data_size -= data_size;
285  }
286 
287  return ret;
288 }
289 
290 uint8_t *av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
291 {
292  const AVEncryptionInitInfo *cur_info;
293  uint8_t *buffer, *cur_buffer;
294  uint32_t i, init_info_count;
295  uint64_t temp_side_data_size;
296 
297  temp_side_data_size = 4;
298  init_info_count = 0;
299  for (cur_info = info; cur_info; cur_info = cur_info->next) {
300  temp_side_data_size += (uint64_t)FF_ENCRYPTION_INIT_INFO_EXTRA + cur_info->system_id_size + cur_info->data_size;
301  if (init_info_count == UINT32_MAX || temp_side_data_size > UINT32_MAX) {
302  return NULL;
303  }
304  init_info_count++;
305 
306  if (cur_info->num_key_ids) {
307  temp_side_data_size += (uint64_t)cur_info->num_key_ids * cur_info->key_id_size;
308  if (temp_side_data_size > UINT32_MAX) {
309  return NULL;
310  }
311  }
312  }
313  *side_data_size = temp_side_data_size;
314 
315  cur_buffer = buffer = av_malloc(*side_data_size);
316  if (!buffer)
317  return NULL;
318 
319  AV_WB32(cur_buffer, init_info_count);
320  cur_buffer += 4;
321  for (cur_info = info; cur_info; cur_info = cur_info->next) {
322  AV_WB32(cur_buffer, cur_info->system_id_size);
323  AV_WB32(cur_buffer + 4, cur_info->num_key_ids);
324  AV_WB32(cur_buffer + 8, cur_info->key_id_size);
325  AV_WB32(cur_buffer + 12, cur_info->data_size);
326  cur_buffer += 16;
327 
328  memcpy(cur_buffer, cur_info->system_id, cur_info->system_id_size);
329  cur_buffer += cur_info->system_id_size;
330  for (i = 0; i < cur_info->num_key_ids; i++) {
331  memcpy(cur_buffer, cur_info->key_ids[i], cur_info->key_id_size);
332  cur_buffer += cur_info->key_id_size;
333  }
334  if (cur_info->data_size > 0) {
335  memcpy(cur_buffer, cur_info->data, cur_info->data_size);
336  cur_buffer += cur_info->data_size;
337  }
338  }
339 
340  return buffer;
341 }
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:90
FF_ENCRYPTION_INIT_INFO_EXTRA
#define FF_ENCRYPTION_INIT_INFO_EXTRA
Definition: encryption_info.c:174
av_encryption_init_info_free
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
Definition: encryption_info.c:214
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:229
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:63
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:23
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:125
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:419
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:80
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:176
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:269
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:39
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:290