comparison mxf.c @ 1779:de2cf54eb68f libavformat

mxf aes decryption support, patch by Reimar, simplified to only look for first crypto context, will be extended once we get files with multiple cryptocontext, and hope that they won't have broken container ul
author bcoudurier
date Sun, 11 Feb 2007 12:50:33 +0000
parents a105c6648aa9
children b33db97089ba
comparison
equal deleted inserted replaced
1778:d8c6b719a070 1779:de2cf54eb68f
44 */ 44 */
45 45
46 //#define DEBUG 46 //#define DEBUG
47 47
48 #include "avformat.h" 48 #include "avformat.h"
49 #include "aes.h"
49 50
50 typedef uint8_t UID[16]; 51 typedef uint8_t UID[16];
51 52
52 enum MXFMetadataSetType { 53 enum MXFMetadataSetType {
53 AnyType, 54 AnyType,
58 Sequence, 59 Sequence,
59 MultipleDescriptor, 60 MultipleDescriptor,
60 Descriptor, 61 Descriptor,
61 Track, 62 Track,
62 EssenceContainerData, 63 EssenceContainerData,
64 CryptoContext,
63 }; 65 };
66
67 typedef struct MXFCryptoContext {
68 UID uid;
69 enum MXFMetadataSetType type;
70 UID context_uid;
71 UID source_container_ul;
72 } MXFCryptoContext;
64 73
65 typedef struct MXFStructuralComponent { 74 typedef struct MXFStructuralComponent {
66 UID uid; 75 UID uid;
67 enum MXFMetadataSetType type; 76 enum MXFMetadataSetType type;
68 UID source_package_uid; 77 UID source_package_uid;
135 int packages_count; 144 int packages_count;
136 MXFMetadataSet **metadata_sets; 145 MXFMetadataSet **metadata_sets;
137 int metadata_sets_count; 146 int metadata_sets_count;
138 const uint8_t *sync_key; 147 const uint8_t *sync_key;
139 AVFormatContext *fc; 148 AVFormatContext *fc;
149 struct AVAES *aesc;
140 } MXFContext; 150 } MXFContext;
141 151
142 typedef struct KLVPacket { 152 typedef struct KLVPacket {
143 UID key; 153 UID key;
144 offset_t offset; 154 offset_t offset;
171 /* partial keys to match */ 181 /* partial keys to match */
172 static const uint8_t mxf_header_partition_pack_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 }; 182 static const uint8_t mxf_header_partition_pack_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 };
173 static const uint8_t mxf_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 }; 183 static const uint8_t mxf_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 };
174 /* complete keys to match */ 184 /* complete keys to match */
175 static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 }; 185 static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
186 static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 };
176 187
177 #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y))) 188 #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))
178 189
179 #define PRINT_KEY(s, x) dprintf("%s %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", s, \ 190 #define PRINT_KEY(s, x) dprintf("%s %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", s, \
180 (x)[0], (x)[1], (x)[2], (x)[3], (x)[4], (x)[5], (x)[6], (x)[7], (x)[8], (x)[9], (x)[10], (x)[11], (x)[12], (x)[13], (x)[14], (x)[15]) 191 (x)[0], (x)[1], (x)[2], (x)[3], (x)[4], (x)[5], (x)[6], (x)[7], (x)[8], (x)[9], (x)[10], (x)[11], (x)[12], (x)[13], (x)[14], (x)[15])
243 } 254 }
244 pkt->size = data_ptr - pkt->data; 255 pkt->size = data_ptr - pkt->data;
245 return 0; 256 return 0;
246 } 257 }
247 258
259 static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv)
260 {
261 static const uint8_t checkv[16] = {0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b};
262 MXFContext *mxf = s->priv_data;
263 ByteIOContext *pb = &s->pb;
264 offset_t end = url_ftell(pb) + klv->length;
265 uint64_t size;
266 uint64_t orig_size;
267 uint64_t plaintext_size;
268 uint8_t ivec[16];
269 uint8_t tmpbuf[16];
270 int index;
271
272 if (!mxf->aesc && s->key && s->keylen == 16) {
273 mxf->aesc = av_malloc(av_aes_size);
274 av_aes_init(mxf->aesc, s->key, 128, 1);
275 }
276 // crypto context
277 url_fskip(pb, klv_decode_ber_length(pb));
278 // plaintext offset
279 klv_decode_ber_length(pb);
280 plaintext_size = get_be64(pb);
281 // source klv key
282 klv_decode_ber_length(pb);
283 get_buffer(pb, klv->key, 16);
284 if (!IS_KLV_KEY(klv, mxf_essence_element_key)) goto err_out;
285 index = mxf_get_stream_index(s, klv);
286 if (index < 0) goto err_out;
287 // source size
288 klv_decode_ber_length(pb);
289 orig_size = get_be64(pb);
290 if (orig_size < plaintext_size) goto err_out;
291 // enc. code
292 size = klv_decode_ber_length(pb);
293 if (size < 32 || size - 32 < orig_size) goto err_out;
294 get_buffer(pb, ivec, 16);
295 get_buffer(pb, tmpbuf, 16);
296 if (mxf->aesc)
297 av_aes_crypt(mxf->aesc, tmpbuf, tmpbuf, 1, ivec, 1);
298 if (memcmp(tmpbuf, checkv, 16))
299 av_log(s, AV_LOG_ERROR, "probably incorrect decryption key\n");
300 size -= 32;
301 av_get_packet(pb, pkt, size);
302 size -= plaintext_size;
303 if (mxf->aesc)
304 av_aes_crypt(mxf->aesc, &pkt->data[plaintext_size],
305 &pkt->data[plaintext_size], size >> 4, ivec, 1);
306 pkt->size = orig_size;
307 pkt->stream_index = index;
308 url_fskip(pb, end - url_ftell(pb));
309 return 0;
310
311 err_out:
312 url_fskip(pb, end - url_ftell(pb));
313 return -1;
314 }
315
248 static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) 316 static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
249 { 317 {
250 MXFContext *mxf = s->priv_data; 318 MXFContext *mxf = s->priv_data;
251 KLVPacket klv; 319 KLVPacket klv;
252 320
257 } 325 }
258 #ifdef DEBUG 326 #ifdef DEBUG
259 PRINT_KEY("read packet", klv.key); 327 PRINT_KEY("read packet", klv.key);
260 #endif 328 #endif
261 if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) { 329 if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {
330 int res = mxf_decrypt_triplet(s, pkt, &klv);
262 mxf->sync_key = mxf_encrypted_triplet_key; 331 mxf->sync_key = mxf_encrypted_triplet_key;
263 av_log(s, AV_LOG_ERROR, "encrypted triplet not supported\n"); 332 if (res < 0) {
264 return -1; 333 av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");
334 return -1;
335 }
336 return 0;
265 } 337 }
266 if (IS_KLV_KEY(klv.key, mxf_essence_element_key)) { 338 if (IS_KLV_KEY(klv.key, mxf_essence_element_key)) {
267 int index = mxf_get_stream_index(s, &klv); 339 int index = mxf_get_stream_index(s, &klv);
268 if (index < 0) { 340 if (index < 0) {
269 av_log(s, AV_LOG_ERROR, "error getting stream index\n"); 341 av_log(s, AV_LOG_ERROR, "error getting stream index\n");
289 static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set) 361 static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set)
290 { 362 {
291 mxf->metadata_sets = av_realloc(mxf->metadata_sets, (mxf->metadata_sets_count + 1) * sizeof(*mxf->metadata_sets)); 363 mxf->metadata_sets = av_realloc(mxf->metadata_sets, (mxf->metadata_sets_count + 1) * sizeof(*mxf->metadata_sets));
292 mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set; 364 mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set;
293 mxf->metadata_sets_count++; 365 mxf->metadata_sets_count++;
366 return 0;
367 }
368
369 static int mxf_read_metadata_cryptographic_context(MXFCryptoContext *cryptocontext, ByteIOContext *pb, int tag)
370 {
371 switch(tag) {
372 case 0xFFFE:
373 get_buffer(pb, cryptocontext->context_uid, 16);
374 break;
375 case 0xFFFD:
376 get_buffer(pb, cryptocontext->source_container_ul, 16);
377 break;
378 }
294 return 0; 379 return 0;
295 } 380 }
296 381
297 static int mxf_read_metadata_content_storage(MXFContext *mxf, ByteIOContext *pb, int tag) 382 static int mxf_read_metadata_content_storage(MXFContext *mxf, ByteIOContext *pb, int tag)
298 { 383 {
599 MXFTrack *material_track = NULL; 684 MXFTrack *material_track = NULL;
600 MXFTrack *source_track = NULL; 685 MXFTrack *source_track = NULL;
601 MXFTrack *temp_track = NULL; 686 MXFTrack *temp_track = NULL;
602 MXFDescriptor *descriptor = NULL; 687 MXFDescriptor *descriptor = NULL;
603 MXFStructuralComponent *component = NULL; 688 MXFStructuralComponent *component = NULL;
689 UID *essence_container_ul = NULL;
604 const MXFCodecUL *codec_ul = NULL; 690 const MXFCodecUL *codec_ul = NULL;
605 const MXFCodecUL *container_ul = NULL; 691 const MXFCodecUL *container_ul = NULL;
606 AVStream *st; 692 AVStream *st;
607 693
608 if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) { 694 if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) {
695 } 781 }
696 #ifdef DEBUG 782 #ifdef DEBUG
697 PRINT_KEY("essence codec ul", descriptor->essence_codec_ul); 783 PRINT_KEY("essence codec ul", descriptor->essence_codec_ul);
698 PRINT_KEY("essence container ul", descriptor->essence_container_ul); 784 PRINT_KEY("essence container ul", descriptor->essence_container_ul);
699 #endif 785 #endif
786 essence_container_ul = &descriptor->essence_container_ul;
787 /* HACK: replacing the original key with mxf_encrypted_essence_container
788 * is not allowed according to s429-6, try to find correct information anyway */
789 if (IS_KLV_KEY(essence_container_ul, mxf_encrypted_essence_container)) {
790 av_log(mxf->fc, AV_LOG_INFO, "broken encrypted mxf file\n");
791 for (k = 0; k < mxf->metadata_sets_count; k++) {
792 MXFMetadataSet *metadata = mxf->metadata_sets[k];
793 if (metadata->type == CryptoContext) {
794 essence_container_ul = &((MXFCryptoContext *)metadata)->source_container_ul;
795 break;
796 }
797 }
798 }
700 /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */ 799 /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */
701 codec_ul = mxf_get_codec_ul(mxf_codec_uls, &descriptor->essence_codec_ul); 800 codec_ul = mxf_get_codec_ul(mxf_codec_uls, &descriptor->essence_codec_ul);
702 st->codec->codec_id = codec_ul->id; 801 st->codec->codec_id = codec_ul->id;
703 if (descriptor->extradata) { 802 if (descriptor->extradata) {
704 st->codec->extradata = descriptor->extradata; 803 st->codec->extradata = descriptor->extradata;
705 st->codec->extradata_size = descriptor->extradata_size; 804 st->codec->extradata_size = descriptor->extradata_size;
706 } 805 }
707 if (st->codec->codec_type == CODEC_TYPE_VIDEO) { 806 if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
708 container_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, &descriptor->essence_container_ul); 807 container_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
709 if (st->codec->codec_id == CODEC_ID_NONE) 808 if (st->codec->codec_id == CODEC_ID_NONE)
710 st->codec->codec_id = container_ul->id; 809 st->codec->codec_id = container_ul->id;
711 st->codec->width = descriptor->width; 810 st->codec->width = descriptor->width;
712 st->codec->height = descriptor->height; 811 st->codec->height = descriptor->height;
713 st->codec->bits_per_sample = descriptor->bits_per_sample; /* Uncompressed */ 812 st->codec->bits_per_sample = descriptor->bits_per_sample; /* Uncompressed */
714 st->need_parsing = 2; /* only parse headers */ 813 st->need_parsing = 2; /* only parse headers */
715 } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) { 814 } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
716 container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, &descriptor->essence_container_ul); 815 container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
717 if (st->codec->codec_id == CODEC_ID_NONE) 816 if (st->codec->codec_id == CODEC_ID_NONE)
718 st->codec->codec_id = container_ul->id; 817 st->codec->codec_id = container_ul->id;
719 st->codec->channels = descriptor->channels; 818 st->codec->channels = descriptor->channels;
720 st->codec->bits_per_sample = descriptor->bits_per_sample; 819 st->codec->bits_per_sample = descriptor->bits_per_sample;
721 st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den; 820 st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den;
757 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }, mxf_read_metadata_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* MPEG 2 Video */ 856 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }, mxf_read_metadata_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* MPEG 2 Video */
758 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }, mxf_read_metadata_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Wave */ 857 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }, mxf_read_metadata_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Wave */
759 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 }, mxf_read_metadata_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* AES3 */ 858 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 }, mxf_read_metadata_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* AES3 */
760 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_metadata_track, sizeof(MXFTrack), Track }, /* Static Track */ 859 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_metadata_track, sizeof(MXFTrack), Track }, /* Static Track */
761 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_metadata_track, sizeof(MXFTrack), Track }, /* Generic Track */ 860 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_metadata_track, sizeof(MXFTrack), Track }, /* Generic Track */
861 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x04,0x01,0x02,0x02,0x00,0x00 }, mxf_read_metadata_cryptographic_context, sizeof(MXFCryptoContext), CryptoContext },
762 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, 0, AnyType }, 862 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, 0, AnyType },
763 }; 863 };
764 864
765 static int mxf_read_sync(ByteIOContext *pb, const uint8_t *key, unsigned size) 865 static int mxf_read_sync(ByteIOContext *pb, const uint8_t *key, unsigned size)
766 { 866 {
821 return -1; 921 return -1;
822 } 922 }
823 #ifdef DEBUG 923 #ifdef DEBUG
824 PRINT_KEY("read header", klv.key); 924 PRINT_KEY("read header", klv.key);
825 #endif 925 #endif
826 if (IS_KLV_KEY(klv.key, mxf_essence_element_key)) { 926 if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key) ||
927 IS_KLV_KEY(klv.key, mxf_essence_element_key)) {
827 /* FIXME avoid seek */ 928 /* FIXME avoid seek */
828 url_fseek(&s->pb, klv.offset, SEEK_SET); 929 url_fseek(&s->pb, klv.offset, SEEK_SET);
829 break; 930 break;
830 } 931 }
831 932
866 break; 967 break;
867 } 968 }
868 av_freep(&mxf->metadata_sets[i]); 969 av_freep(&mxf->metadata_sets[i]);
869 } 970 }
870 av_freep(&mxf->metadata_sets); 971 av_freep(&mxf->metadata_sets);
972 av_freep(&mxf->aesc);
871 return 0; 973 return 0;
872 } 974 }
873 975
874 static int mxf_probe(AVProbeData *p) { 976 static int mxf_probe(AVProbeData *p) {
875 uint8_t *bufp = p->buf; 977 uint8_t *bufp = p->buf;