Revision 80a289b9 libavformat/mxf.c

View differences:

libavformat/mxf.c
46 46
//#define DEBUG
47 47

  
48 48
#include "avformat.h"
49
#include "aes.h"
49 50

  
50 51
typedef uint8_t UID[16];
51 52

  
......
60 61
    Descriptor,
61 62
    Track,
62 63
    EssenceContainerData,
64
    CryptoContext,
63 65
};
64 66

  
67
typedef struct MXFCryptoContext {
68
    UID uid;
69
    enum MXFMetadataSetType type;
70
    UID context_uid;
71
    UID source_container_ul;
72
} MXFCryptoContext;
73

  
65 74
typedef struct MXFStructuralComponent {
66 75
    UID uid;
67 76
    enum MXFMetadataSetType type;
......
137 146
    int metadata_sets_count;
138 147
    const uint8_t *sync_key;
139 148
    AVFormatContext *fc;
149
    struct AVAES *aesc;
140 150
} MXFContext;
141 151

  
142 152
typedef struct KLVPacket {
......
173 183
static const uint8_t mxf_essence_element_key[]             = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 };
174 184
/* complete keys to match */
175 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 188
#define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))
178 189

  
......
245 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 316
static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
249 317
{
250 318
    MXFContext *mxf = s->priv_data;
......
259 327
        PRINT_KEY("read packet", klv.key);
260 328
#endif
261 329
        if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {
330
            int res = mxf_decrypt_triplet(s, pkt, &klv);
262 331
            mxf->sync_key = mxf_encrypted_triplet_key;
263
            av_log(s, AV_LOG_ERROR, "encrypted triplet not supported\n");
264
            return -1;
332
            if (res < 0) {
333
                av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");
334
                return -1;
335
            }
336
            return 0;
265 337
        }
266 338
        if (IS_KLV_KEY(klv.key, mxf_essence_element_key)) {
267 339
            int index = mxf_get_stream_index(s, &klv);
......
294 366
    return 0;
295 367
}
296 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
    }
379
    return 0;
380
}
381

  
297 382
static int mxf_read_metadata_content_storage(MXFContext *mxf, ByteIOContext *pb, int tag)
298 383
{
299 384
    switch (tag) {
......
601 686
        MXFTrack *temp_track = NULL;
602 687
        MXFDescriptor *descriptor = NULL;
603 688
        MXFStructuralComponent *component = NULL;
689
        UID *essence_container_ul = NULL;
604 690
        const MXFCodecUL *codec_ul = NULL;
605 691
        const MXFCodecUL *container_ul = NULL;
606 692
        AVStream *st;
......
697 783
        PRINT_KEY("essence codec     ul", descriptor->essence_codec_ul);
698 784
        PRINT_KEY("essence container ul", descriptor->essence_container_ul);
699 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 799
        /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */
701 800
        codec_ul = mxf_get_codec_ul(mxf_codec_uls, &descriptor->essence_codec_ul);
702 801
        st->codec->codec_id = codec_ul->id;
......
705 804
            st->codec->extradata_size = descriptor->extradata_size;
706 805
        }
707 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 808
            if (st->codec->codec_id == CODEC_ID_NONE)
710 809
                st->codec->codec_id = container_ul->id;
711 810
            st->codec->width = descriptor->width;
......
713 812
            st->codec->bits_per_sample = descriptor->bits_per_sample; /* Uncompressed */
714 813
            st->need_parsing = 2; /* only parse headers */
715 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 816
            if (st->codec->codec_id == CODEC_ID_NONE)
718 817
                st->codec->codec_id = container_ul->id;
719 818
            st->codec->channels = descriptor->channels;
......
759 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 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 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 862
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, 0, AnyType },
763 863
};
764 864

  
......
823 923
#ifdef DEBUG
824 924
        PRINT_KEY("read header", klv.key);
825 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 928
            /* FIXME avoid seek */
828 929
            url_fseek(&s->pb, klv.offset, SEEK_SET);
829 930
            break;
......
868 969
        av_freep(&mxf->metadata_sets[i]);
869 970
    }
870 971
    av_freep(&mxf->metadata_sets);
972
    av_freep(&mxf->aesc);
871 973
    return 0;
872 974
}
873 975

  

Also available in: Unified diff