FFmpeg  4.0
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 {
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)) {
57  return NULL;
58  }
59 
60  return info;
61 }
62 
64 {
65  AVEncryptionInfo *ret;
66 
68  if (!ret)
69  return NULL;
70 
71  ret->scheme = info->scheme;
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 {
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 
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 
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)) {
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]) {
203  return NULL;
204  }
205  }
206  }
207 
208  return info;
209 }
210 
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 
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 
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 }
#define NULL
Definition: coverity.c:32
int size
void av_encryption_info_free(AVEncryptionInfo *info)
Frees the given encryption info object.
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.
Memory handling functions.
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
uint32_t crypt_byte_block
Only used for pattern encryption.
This describes encryption info for a packet.
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...
uint32_t skip_byte_block
Only used for pattern encryption.
static char buffer[20]
Definition: seek.c:32
uint8_t
uint8_t ** key_ids
An array of key IDs this initialization data is for.
AVEncryptionInfo * av_encryption_info_clone(const AVEncryptionInfo *info)
Allocates an AVEncryptionInfo structure with a copy of the given data.
#define av_malloc(s)
unsigned int bytes_of_clear_data
The number of bytes that are clear.
#define AV_RB32
Definition: intreadwrite.h:130
uint32_t scheme
The fourcc encryption scheme.
This describes info used to initialize an encryption key system.
uint8_t * iv
The initialization vector.
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.
AVSubsampleEncryptionInfo * subsamples
An array of subsample encryption info specifying how parts of the sample are encrypted.
uint32_t num_key_ids
The number of key IDs.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
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.
#define AV_WB32(p, v)
Definition: intreadwrite.h:419
unsigned int bytes_of_protected_data
The number of bytes that are protected.
uint32_t subsample_count
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.
uint32_t key_id_size
The number of bytes in each key ID.
uint8_t * key_id
The ID of the key used to encrypt the packet.
uint8_t * data
Key-system specific initialization data.
#define FF_ENCRYPTION_INFO_EXTRA
This file is part of FFmpeg.
#define av_free(p)
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...
#define FF_ENCRYPTION_INIT_INFO_EXTRA
uint8_t * system_id
A unique identifier for the key system this is for, can be NULL if it is not known.
void * av_mallocz_array(size_t nmemb, size_t size)
Allocate a memory block for an array with av_mallocz().
Definition: mem.c:191