FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/hls_sample_encryption.c
Date: 2026-04-30 08:04:40
Exec Total Coverage
Lines: 0 198 0.0%
Functions: 0 12 0.0%
Branches: 0 118 0.0%

Line Branch Exec Source
1 /*
2 * Apple HTTP Live Streaming Sample Encryption/Decryption
3 *
4 * Copyright (c) 2021 Nachiket Tarate
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /**
24 * @file
25 * Apple HTTP Live Streaming Sample Encryption
26 * https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption
27 */
28
29 #include "libavutil/aes.h"
30 #include "libavutil/channel_layout.h"
31 #include "libavutil/mem.h"
32
33 #include "hls_sample_encryption.h"
34
35 #include "libavcodec/adts_header.h"
36 #include "libavcodec/adts_parser.h"
37 #include "libavcodec/ac3tab.h"
38 #include "libavcodec/ac3_parser_internal.h"
39
40
41 typedef struct NALUnit {
42 uint8_t *data;
43 int type;
44 int length;
45 int start_code_length;
46 } NALUnit;
47
48 typedef struct AudioFrame {
49 uint8_t *data;
50 int length;
51 int header_length;
52 } AudioFrame;
53
54 typedef struct CodecParserContext {
55 const uint8_t *buf_ptr;
56 const uint8_t *buf_end;
57 } CodecParserContext;
58
59 static const int eac3_sample_rate_tab[] = { 48000, 44100, 32000, 0 };
60
61 void ff_hls_senc_read_audio_setup_info(HLSAudioSetupInfo *info, const uint8_t *buf, size_t size)
62 {
63 if (size < 8)
64 return;
65
66 info->codec_tag = AV_RL32(buf);
67
68 /* Always keep this list in sync with the one from hls_read_header() */
69 if (info->codec_tag == MKTAG('z','a','a','c'))
70 info->codec_id = AV_CODEC_ID_AAC;
71 else if (info->codec_tag == MKTAG('z','a','c','3'))
72 info->codec_id = AV_CODEC_ID_AC3;
73 else if (info->codec_tag == MKTAG('z','e','c','3'))
74 info->codec_id = AV_CODEC_ID_EAC3;
75 else
76 info->codec_id = AV_CODEC_ID_NONE;
77
78 buf += 4;
79 info->priming = AV_RL16(buf);
80 buf += 2;
81 info->version = *buf++;
82 info->setup_data_length = *buf++;
83
84 if (info->setup_data_length > size - 8)
85 info->setup_data_length = size - 8;
86
87 if (info->setup_data_length > HLS_MAX_AUDIO_SETUP_DATA_LEN)
88 return;
89
90 memcpy(info->setup_data, buf, info->setup_data_length);
91 memset(info->setup_data + info->setup_data_length, 0, AV_INPUT_BUFFER_PADDING_SIZE);
92 }
93
94 int ff_hls_senc_parse_audio_setup_info(AVStream *st, HLSAudioSetupInfo *info)
95 {
96 int ret = 0;
97
98 st->codecpar->codec_tag = info->codec_tag;
99
100 if (st->codecpar->codec_id == AV_CODEC_ID_AAC)
101 return 0;
102
103 if (st->codecpar->codec_id != AV_CODEC_ID_AC3 && st->codecpar->codec_id != AV_CODEC_ID_EAC3)
104 return AVERROR_INVALIDDATA;
105
106 if (st->codecpar->codec_id == AV_CODEC_ID_AC3) {
107 AC3HeaderInfo *ac3hdr = NULL;
108
109 ret = avpriv_ac3_parse_header(&ac3hdr, info->setup_data, info->setup_data_length);
110 if (ret < 0) {
111 av_free(ac3hdr);
112 return ret;
113 }
114
115 st->codecpar->sample_rate = ac3hdr->sample_rate;
116 av_channel_layout_uninit(&st->codecpar->ch_layout);
117 av_channel_layout_from_mask(&st->codecpar->ch_layout, ac3hdr->channel_layout);
118 st->codecpar->bit_rate = ac3hdr->bit_rate;
119
120 av_free(ac3hdr);
121 } else { /* Parse 'dec3' EC3SpecificBox */
122 GetBitContext gb;
123 uint64_t mask;
124 int data_rate, fscod, acmod, lfeon;
125
126 ret = init_get_bits8(&gb, info->setup_data, info->setup_data_length);
127 if (ret < 0)
128 return AVERROR_INVALIDDATA;
129
130 data_rate = get_bits(&gb, 13);
131 skip_bits(&gb, 3);
132 fscod = get_bits(&gb, 2);
133 skip_bits(&gb, 10);
134 acmod = get_bits(&gb, 3);
135 lfeon = get_bits(&gb, 1);
136
137 st->codecpar->sample_rate = eac3_sample_rate_tab[fscod];
138
139 mask = ff_ac3_channel_layout_tab[acmod];
140 if (lfeon)
141 mask |= AV_CH_LOW_FREQUENCY;
142
143 av_channel_layout_uninit(&st->codecpar->ch_layout);
144 av_channel_layout_from_mask(&st->codecpar->ch_layout, mask);
145
146 st->codecpar->bit_rate = data_rate*1000;
147 }
148
149 return 0;
150 }
151
152 /*
153 * Remove start code emulation prevention 0x03 bytes
154 */
155 static void remove_scep_3_bytes(NALUnit *nalu)
156 {
157 int i = 0;
158 int j = 0;
159
160 uint8_t *data = nalu->data;
161
162 while (i < nalu->length) {
163 if (nalu->length - i > 3 && AV_RB24(&data[i]) == 0x000003) {
164 data[j++] = data[i++];
165 data[j++] = data[i++];
166 i++;
167 } else {
168 data[j++] = data[i++];
169 }
170 }
171
172 nalu->length = j;
173 }
174
175 static int get_next_nal_unit(CodecParserContext *ctx, NALUnit *nalu)
176 {
177 const uint8_t *nalu_start = ctx->buf_ptr;
178
179 if (ctx->buf_end - ctx->buf_ptr >= 4 && AV_RB32(ctx->buf_ptr) == 0x00000001)
180 nalu->start_code_length = 4;
181 else if (ctx->buf_end - ctx->buf_ptr >= 3 && AV_RB24(ctx->buf_ptr) == 0x000001)
182 nalu->start_code_length = 3;
183 else /* No start code at the beginning of the NAL unit */
184 return -1;
185
186 ctx->buf_ptr += nalu->start_code_length;
187
188 while (ctx->buf_ptr < ctx->buf_end) {
189 if (ctx->buf_end - ctx->buf_ptr >= 4 && AV_RB32(ctx->buf_ptr) == 0x00000001)
190 break;
191 else if (ctx->buf_end - ctx->buf_ptr >= 3 && AV_RB24(ctx->buf_ptr) == 0x000001)
192 break;
193 ctx->buf_ptr++;
194 }
195
196 nalu->data = (uint8_t *)nalu_start + nalu->start_code_length;
197 nalu->length = ctx->buf_ptr - nalu->data;
198 nalu->type = *nalu->data & 0x1F;
199
200 return 0;
201 }
202
203 static int decrypt_nal_unit(HLSCryptoContext *crypto_ctx, NALUnit *nalu)
204 {
205 int ret = 0;
206 int rem_bytes;
207 uint8_t *data;
208 uint8_t iv[16];
209
210 ret = av_aes_init(crypto_ctx->aes_ctx, crypto_ctx->key, 16 * 8, 1);
211 if (ret < 0)
212 return ret;
213
214 /* Remove start code emulation prevention 0x03 bytes */
215 remove_scep_3_bytes(nalu);
216
217 data = nalu->data + 32;
218 rem_bytes = nalu->length - 32;
219
220 memcpy(iv, crypto_ctx->iv, 16);
221
222 while (rem_bytes > 0) {
223 if (rem_bytes > 16) {
224 av_aes_crypt(crypto_ctx->aes_ctx, data, data, 1, iv, 1);
225 data += 16;
226 rem_bytes -= 16;
227 }
228 data += FFMIN(144, rem_bytes);
229 rem_bytes -= FFMIN(144, rem_bytes);
230 }
231
232 return 0;
233 }
234
235 static int decrypt_video_frame(HLSCryptoContext *crypto_ctx, AVPacket *pkt)
236 {
237 int ret = 0;
238 CodecParserContext ctx;
239 NALUnit nalu;
240 uint8_t *data_ptr;
241 int move_nalu = 0;
242
243 memset(&ctx, 0, sizeof(ctx));
244 ctx.buf_ptr = pkt->data;
245 ctx.buf_end = pkt->data + pkt->size;
246
247 data_ptr = pkt->data;
248
249 while (ctx.buf_ptr < ctx.buf_end) {
250 memset(&nalu, 0, sizeof(nalu));
251 ret = get_next_nal_unit(&ctx, &nalu);
252 if (ret < 0)
253 return ret;
254 if ((nalu.type == 0x01 || nalu.type == 0x05) && nalu.length > 48) {
255 int encrypted_nalu_length = nalu.length;
256 ret = decrypt_nal_unit(crypto_ctx, &nalu);
257 if (ret < 0)
258 return ret;
259 move_nalu = nalu.length != encrypted_nalu_length;
260 }
261 if (move_nalu)
262 memmove(data_ptr, nalu.data - nalu.start_code_length, nalu.start_code_length + nalu.length);
263 data_ptr += nalu.start_code_length + nalu.length;
264 }
265
266 av_shrink_packet(pkt, data_ptr - pkt->data);
267
268 return 0;
269 }
270
271 static int get_next_adts_frame(CodecParserContext *ctx, AudioFrame *frame)
272 {
273 int ret = 0;
274
275 AACADTSHeaderInfo *adts_hdr = NULL;
276
277 /* Find next sync word 0xFFF */
278 while (ctx->buf_ptr < ctx->buf_end - 1) {
279 if (*ctx->buf_ptr == 0xFF && (*(ctx->buf_ptr + 1) & 0xF0) == 0xF0)
280 break;
281 ctx->buf_ptr++;
282 }
283
284 if (ctx->buf_ptr >= ctx->buf_end - 1)
285 return -1;
286
287 frame->data = (uint8_t*)ctx->buf_ptr;
288
289 ret = avpriv_adts_header_parse (&adts_hdr, frame->data, ctx->buf_end - frame->data);
290 if (ret < 0)
291 return ret;
292
293 frame->header_length = adts_hdr->crc_absent ? AV_AAC_ADTS_HEADER_SIZE : AV_AAC_ADTS_HEADER_SIZE + 2;
294 frame->length = adts_hdr->frame_length;
295
296 av_free(adts_hdr);
297
298 return 0;
299 }
300
301 static int get_next_ac3_eac3_sync_frame(CodecParserContext *ctx, AudioFrame *frame)
302 {
303 int ret = 0;
304
305 AC3HeaderInfo *hdr = NULL;
306
307 /* Find next sync word 0x0B77 */
308 while (ctx->buf_ptr < ctx->buf_end - 1) {
309 if (*ctx->buf_ptr == 0x0B && *(ctx->buf_ptr + 1) == 0x77)
310 break;
311 ctx->buf_ptr++;
312 }
313
314 if (ctx->buf_ptr >= ctx->buf_end - 1)
315 return -1;
316
317 frame->data = (uint8_t*)ctx->buf_ptr;
318 frame->header_length = 0;
319
320 ret = avpriv_ac3_parse_header(&hdr, frame->data, ctx->buf_end - frame->data);
321 if (ret < 0) {
322 av_free(hdr);
323 return ret;
324 }
325
326 frame->length = hdr->frame_size;
327
328 av_free(hdr);
329
330 return 0;
331 }
332
333 static int get_next_sync_frame(enum AVCodecID codec_id, CodecParserContext *ctx, AudioFrame *frame)
334 {
335 if (codec_id == AV_CODEC_ID_AAC)
336 return get_next_adts_frame(ctx, frame);
337 else if (codec_id == AV_CODEC_ID_AC3 || codec_id == AV_CODEC_ID_EAC3)
338 return get_next_ac3_eac3_sync_frame(ctx, frame);
339 else
340 return AVERROR_INVALIDDATA;
341 }
342
343 static int decrypt_sync_frame(enum AVCodecID codec_id, HLSCryptoContext *crypto_ctx, AudioFrame *frame)
344 {
345 int ret = 0;
346 uint8_t *data;
347 int num_of_encrypted_blocks;
348
349 ret = av_aes_init(crypto_ctx->aes_ctx, crypto_ctx->key, 16 * 8, 1);
350 if (ret < 0)
351 return ret;
352
353 data = frame->data + frame->header_length + 16;
354
355 num_of_encrypted_blocks = (frame->length - frame->header_length - 16)/16;
356
357 av_aes_crypt(crypto_ctx->aes_ctx, data, data, num_of_encrypted_blocks, crypto_ctx->iv, 1);
358
359 return 0;
360 }
361
362 static int decrypt_audio_frame(enum AVCodecID codec_id, HLSCryptoContext *crypto_ctx, AVPacket *pkt)
363 {
364 int ret = 0;
365 CodecParserContext ctx;
366 AudioFrame frame;
367
368 memset(&ctx, 0, sizeof(ctx));
369 ctx.buf_ptr = pkt->data;
370 ctx.buf_end = pkt->data + pkt->size;
371
372 while (ctx.buf_ptr < ctx.buf_end) {
373 memset(&frame, 0, sizeof(frame));
374 ret = get_next_sync_frame(codec_id, &ctx, &frame);
375 if (ret < 0)
376 return ret;
377 if (frame.length - frame.header_length > 31) {
378 ret = decrypt_sync_frame(codec_id, crypto_ctx, &frame);
379 if (ret < 0)
380 return ret;
381 }
382 ctx.buf_ptr += frame.length;
383 }
384
385 return 0;
386 }
387
388 int ff_hls_senc_decrypt_frame(enum AVCodecID codec_id, HLSCryptoContext *crypto_ctx, AVPacket *pkt)
389 {
390 if (codec_id == AV_CODEC_ID_H264)
391 return decrypt_video_frame(crypto_ctx, pkt);
392 else if (codec_id == AV_CODEC_ID_AAC || codec_id == AV_CODEC_ID_AC3 || codec_id == AV_CODEC_ID_EAC3)
393 return decrypt_audio_frame(codec_id, crypto_ctx, pkt);
394
395 return AVERROR_INVALIDDATA;
396 }
397