[Ffmpeg-devel] [RFC] MXF AES decryption

Baptiste Coudurier baptiste.coudurier
Thu Jan 11 12:35:34 CET 2007


Reimar D?ffinger wrote:
> Hello,
> On Thu, Jan 11, 2007 at 11:41:43AM +0100, Baptiste Coudurier wrote:
>> Reimar D?ffinger wrote:
> [...]
>>> 2) Seeking does not work with encrypted files
>> An implementation using MXF Index would be nice.
> 
> The current seeking function IMO still should be kept and fixed.
> I was thinking of making mxf_read_sync work more like the mpeg header
> search stuff, i.e. just search for the next occurence of 0x06,0x0E,0x2B,0x34
> and then returning the full 16 bytes from that position or so.
> The search function could then first look for a mxf_essence_element_key
> and then get the next either mxf_essence_element_key or
> mxf_encrypted_triplet_key, whichever comes first. I think that should
> work for both cases.

Sounds good

>>> 3) SSL configure stuff is needed - or alternatively a standalone AES
>>> implementation might be interesting as well...
>>> 4) Code needs quite a bit of general cleanup, it seems much too
>>> complicated to me for what it does
>> It seems pretty clear to me. What looks like complicated ? MXF is
>> complicated, take a look at mxflib for example. Also code is prepared to
>> support more complicated files (think about OP3C, OP2B, ...)
> 
> Exactly the function you complained about being too complicated.

Ok

>>> @@ -173,6 +174,7 @@
>>>  /* partial keys to match */
>>>  static const uint8_t mxf_header_partition_pack_key[]       = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 };
>>>  static const uint8_t mxf_essence_element_key[]             = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 };
>>> +static const uint8_t mxf_encrypted_triplet_key[]           = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
>>>  
>> Key is not partial.
> 
> ?? oh, you mean because of the comment? Well, should I add a "/* full
> key to match */" or how?

Yes

>>>  #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))
>>>  
>>> @@ -181,20 +183,8 @@
>>>  
>>>  static int64_t klv_decode_ber_length(ByteIOContext *pb)
>>>  {
>>> -    int64_t size = 0;
>>> -    uint8_t length = get_byte(pb);
>>> -    int type = length >> 7;
>>> -
>>> -    if (type) { /* long form */
>>> -        int bytes_num = length & 0x7f;
>>> -        /* SMPTE 379M 5.3.4 guarantee that bytes_num must not exceed 8 bytes */
>>> -        if (bytes_num > 8)
>>> -            return -1;
>>> -        while (bytes_num--)
>>> -            size = size << 8 | get_byte(pb);
>>> -    } else {
>>> -        size = length & 0x7f;
>>> -    }
>>> +    uint64_t size;
>>> +    GET_BER(size, get_byte(pb), return -1;);
>>>      return size;
>>>  }
>> IMHO GET_BER is unneeded since it is only used in mxf.c, also return
>> -1;); looks quite ugly.
> 
> Huh? Why "unneeded"? The problem is that klv_decode_ber_length can't be
> used on memory, how else to solve this except making two different
> functions? Though this change might be unneeded. Anyway, my GET_BER is a
> bit simplified compared to this function, maybe you can say if you're
> interested in me porting these simplifications (if you consider them
> such).

Yes please do.

>>>
>>> [...]
>>>

>> Is it needed to check for size every 2 lines ?
> 
> If esp. we decode directly there probably is no reason for this function
> to operate on memory but instead could read directly from file. In this
> case all the checks could be removed. As I said, the code needs some
> serious cleanup, esp. this part.

I feel like more comfortable with reading from the file directly.

>>> -        if (IS_KLV_KEY(klv.key, mxf_essence_element_key)) {
>>> -            int index = mxf_get_stream_index(s, &klv);
>>> +        if (IS_KLV_KEY(klv.key, mxf_essence_element_key) ||
>>> +            IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {
>>> +            int index;
>>> +            av_get_packet(&s->pb, pkt, klv.length);
>>> +            if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key) &&
>>> +                get_enc_src_klv(s, pkt, &klv) < 0)
>>> +                av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");
>>> +            index = mxf_get_stream_index(s, &klv);
>>>              if (index < 0) {
>>>                  av_log(s, AV_LOG_ERROR, "error getting stream index\n");
>>> -                url_fskip(&s->pb, klv.length);
>>> +                av_free_packet(pkt);
>>>                  return -1;
>>>              }
>>>              /* check for 8 channels AES3 element */
>>>              if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) {
>>>                  if (mxf_get_d10_aes3_packet(&s->pb, s->streams[index], pkt, klv.length) < 0) {
>>>                      av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
>>> +                    av_free_packet(pkt);
>>>                      return -1;
>>>                  }
>>> -            } else
>>> -                av_get_packet(&s->pb, pkt, klv.length);
>>> +            }
>>>              pkt->stream_index = index;
>>>              return 0;
>>>          } else
>> Freeing packet is overkill, I have some files with broken track number,
>> that's why code is that way. Useless allocating/freeing should be
>> avoided where it can.
> 
> I was not aware that not freeing packets is acceptable and handled
> correctly...

Ok. Somehow I think that checking for encrypted key before, and calling
mxf_decrypt_triplet directly would be cleaner. At this point maybe using
function pointers like in read_header, and getting packet. There will be
3 ways of retrieving data now. What do you think ?

>>>
>>> [...]
>>>

>> That key is Encrypted essence container label, also that key can be used
>> with JPEG 2000 like my files are.
> 
> So where to get the codec id from??
> 

Picture essence coding ul in descriptor, if present. If not then I need
to dig further in specs.

-- 
Baptiste COUDURIER                              GnuPG Key Id: 0x5C1ABAAA
SMARTJOG S.A.                                    http://www.smartjog.com
Key fingerprint                 8D77134D20CC9220201FC5DB0AC9325C5C1ABAAA
Phone: +33 1 49966312




More information about the ffmpeg-devel mailing list