1 /*****************************************************************
2 |
3 |    AP4 - OMA DCF support
4 |
5 |    Copyright 2002-2008 Axiomatic Systems, LLC
6 |
7 |
8 |    This file is part of Bento4/AP4 (MP4 Atom Processing Library).
9 |
10 |    Unless you have obtained Bento4 under a difference license,
11 |    this version of Bento4 is Bento4|GPL.
12 |    Bento4|GPL is free software; you can redistribute it and/or modify
13 |    it under the terms of the GNU General Public License as published by
14 |    the Free Software Foundation; either version 2, or (at your option)
15 |    any later version.
16 |
17 |    Bento4|GPL is distributed in the hope that it will be useful,
18 |    but WITHOUT ANY WARRANTY; without even the implied warranty of
19 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 |    GNU General Public License for more details.
21 |
22 |    You should have received a copy of the GNU General Public License
23 |    along with Bento4|GPL; see the file COPYING.  If not, write to the
24 |    Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 |    02111-1307, USA.
26 |
27 ****************************************************************/
28 
29 #ifndef _AP4_OMA_DCF_H_
30 #define _AP4_OMA_DCF_H_
31 
32 /*----------------------------------------------------------------------
33 |   includes
34 +---------------------------------------------------------------------*/
35 #include "Ap4Types.h"
36 #include "Ap4SampleEntry.h"
37 #include "Ap4Atom.h"
38 #include "Ap4AtomFactory.h"
39 #include "Ap4SampleDescription.h"
40 #include "Ap4Processor.h"
41 #include "Ap4Protection.h"
42 #include "Ap4DynamicCast.h"
43 
44 /*----------------------------------------------------------------------
45 |   class references
46 +---------------------------------------------------------------------*/
47 class AP4_OdafAtom;
48 class AP4_StreamCipher;
49 class AP4_CbcStreamCipher;
50 class AP4_CtrStreamCipher;
51 
52 /*----------------------------------------------------------------------
53 |   constants
54 +---------------------------------------------------------------------*/
55 const AP4_UI32 AP4_PROTECTION_SCHEME_TYPE_OMA = AP4_ATOM_TYPE('o','d','k','m');
56 const AP4_UI32 AP4_PROTECTION_SCHEME_VERSION_OMA_20 = 0x00000200;
57 const AP4_UI32 AP4_OMA_DCF_BRAND_ODCF = AP4_ATOM_TYPE('o','d','c','f');
58 const AP4_UI32 AP4_OMA_DCF_BRAND_OPF2 = AP4_ATOM_TYPE('o','p','f','2');
59 
60 typedef enum {
61     AP4_OMA_DCF_CIPHER_MODE_CTR,
62     AP4_OMA_DCF_CIPHER_MODE_CBC
63 } AP4_OmaDcfCipherMode;
64 
65 /*----------------------------------------------------------------------
66 |   AP4_OmaDcfAtomDecrypter
67 +---------------------------------------------------------------------*/
68 class AP4_OmaDcfAtomDecrypter {
69 public:
70     // class methods
71     static AP4_Result DecryptAtoms(AP4_AtomParent&                  atoms,
72                                    AP4_Processor::ProgressListener* listener,
73                                    AP4_BlockCipherFactory*          block_cipher_factory,
74                                    AP4_ProtectionKeyMap&            key_map);
75 
76     // Returns a byte stream that will produce the decrypted data found
77     // in the 'odda' child atom of an 'odrm' atom
78     static AP4_Result CreateDecryptingStream(AP4_ContainerAtom&      odrm_atom,
79                                              const AP4_UI08*         key,
80                                              AP4_Size                key_size,
81                                              AP4_BlockCipherFactory* block_cipher_factory,
82                                              AP4_ByteStream*&        stream);
83 
84     // Returns a byte stream that will produce the decrypted data from
85     // an encrypted stream where the IV follows the encrypted bytes.
86     // This method is normally not called directly: most callers will call
87     // the stream factory that takes an 'odrm' atom as an input parameter
88     static AP4_Result CreateDecryptingStream(AP4_OmaDcfCipherMode    mode,
89                                              AP4_ByteStream&         encrypted_stream,
90                                              AP4_LargeSize           cleartext_size,
91                                              const AP4_UI08*         key,
92                                              AP4_Size                key_size,
93                                              AP4_BlockCipherFactory* block_cipher_factory,
94                                              AP4_ByteStream*&        stream);
95 };
96 
97 /*----------------------------------------------------------------------
98 |   AP4_OmaDcfSampleDecrypter
99 +---------------------------------------------------------------------*/
100 class AP4_OmaDcfSampleDecrypter : public AP4_SampleDecrypter
101 {
102 public:
103     // factory
104     static AP4_Result Create(AP4_ProtectedSampleDescription* sample_description,
105                              const AP4_UI08*                 key,
106                              AP4_Size                        key_size,
107                              AP4_BlockCipherFactory*         block_cipher_factory,
108                              AP4_OmaDcfSampleDecrypter*&     cipher);
109 
110     // constructor and destructor
AP4_OmaDcfSampleDecrypter(AP4_Size iv_length,bool selective_encryption)111     AP4_OmaDcfSampleDecrypter(AP4_Size iv_length,
112                               bool     selective_encryption) :
113         m_IvLength(iv_length),
114         m_KeyIndicatorLength(0),
115         m_SelectiveEncryption(selective_encryption) {}
116 
117 protected:
118     AP4_Size m_IvLength;
119     AP4_Size m_KeyIndicatorLength;
120     bool     m_SelectiveEncryption;
121 };
122 
123 /*----------------------------------------------------------------------
124 |   AP4_OmaDcfCtrSampleDecrypter
125 +---------------------------------------------------------------------*/
126 class AP4_OmaDcfCtrSampleDecrypter : public AP4_OmaDcfSampleDecrypter
127 {
128 public:
129     // constructor and destructor
130     AP4_OmaDcfCtrSampleDecrypter(AP4_BlockCipher* block_cipher,
131                                  AP4_Size         iv_length,
132                                  bool             selective_encryption);
133     ~AP4_OmaDcfCtrSampleDecrypter();
134 
135     // methods
136     virtual AP4_Result DecryptSampleData(AP4_DataBuffer& data_in,
137                                          AP4_DataBuffer& data_out,
138                                          const AP4_UI08* iv = NULL);
139     virtual AP4_Size   GetDecryptedSampleSize(AP4_Sample& sample);
140 
141 private:
142     // members
143     AP4_CtrStreamCipher* m_Cipher;
144 };
145 
146 /*----------------------------------------------------------------------
147 |   AP4_OmaDcfCbcSampleDecrypter
148 +---------------------------------------------------------------------*/
149 class AP4_OmaDcfCbcSampleDecrypter : public AP4_OmaDcfSampleDecrypter
150 {
151 public:
152     // constructor and destructor
153     AP4_OmaDcfCbcSampleDecrypter(AP4_BlockCipher* block_cipher,
154                                  bool             selective_encryption);
155     ~AP4_OmaDcfCbcSampleDecrypter();
156 
157     // methods
158     virtual AP4_Result DecryptSampleData(AP4_DataBuffer& data_in,
159                                          AP4_DataBuffer& data_out,
160                                          const AP4_UI08* iv = NULL);
161     virtual AP4_Size   GetDecryptedSampleSize(AP4_Sample& sample);
162 
163 private:
164     // members
165     AP4_CbcStreamCipher* m_Cipher;
166 };
167 
168 /*----------------------------------------------------------------------
169 |   AP4_OmaDcfTrackDecrypter
170 +---------------------------------------------------------------------*/
171 class AP4_OmaDcfTrackDecrypter : public AP4_Processor::TrackHandler {
172 public:
173     // constructor
174     static AP4_Result Create(const AP4_UI08*                 key,
175                              AP4_Size                        key_size,
176                              AP4_ProtectedSampleDescription* sample_description,
177                              AP4_SampleEntry*                sample_entry,
178                              AP4_BlockCipherFactory*         block_cipher_factory,
179                              AP4_OmaDcfTrackDecrypter*&      decrypter);
180     virtual ~AP4_OmaDcfTrackDecrypter();
181 
182     // methods
183     virtual AP4_Size   GetProcessedSampleSize(AP4_Sample& sample);
184     virtual AP4_Result ProcessTrack();
185     virtual AP4_Result ProcessSample(AP4_DataBuffer& data_in,
186                                      AP4_DataBuffer& data_out);
187 
188 private:
189     // constructor
190     AP4_OmaDcfTrackDecrypter(AP4_OmaDcfSampleDecrypter* cipher,
191                              AP4_SampleEntry*           sample_entry,
192                              AP4_UI32                   original_format);
193 
194     // members
195     AP4_OmaDcfSampleDecrypter* m_Cipher;
196     AP4_SampleEntry*           m_SampleEntry;
197     AP4_UI32                   m_OriginalFormat;
198 };
199 
200 /*----------------------------------------------------------------------
201 |   AP4_OmaDcfSampleEncrypter
202 +---------------------------------------------------------------------*/
203 class AP4_OmaDcfSampleEncrypter
204 {
205 public:
206     // constructor and destructor
207     AP4_OmaDcfSampleEncrypter(const AP4_UI08* salt); // salt is only 8 bytes
~AP4_OmaDcfSampleEncrypter()208     virtual ~AP4_OmaDcfSampleEncrypter() {}
209 
210     // methods
211     virtual AP4_Result EncryptSampleData(AP4_DataBuffer& data_in,
212                                          AP4_DataBuffer& data_out,
213                                          AP4_UI64        bso,
214                                          bool            skip_encryption) = 0;
215     virtual AP4_Size   GetEncryptedSampleSize(AP4_Sample& sample) = 0;
216 
217 protected:
218     // members
219     AP4_UI08 m_Salt[16];
220 };
221 
222 /*----------------------------------------------------------------------
223 |   AP4_OmaDcfCtrSampleEncrypter
224 +---------------------------------------------------------------------*/
225 class AP4_OmaDcfCtrSampleEncrypter : public AP4_OmaDcfSampleEncrypter
226 {
227 public:
228     // constructor and destructor
229     AP4_OmaDcfCtrSampleEncrypter(AP4_BlockCipher* block_cipher,
230                                  const AP4_UI08*  salt); // salt is only 8 bytes
231     ~AP4_OmaDcfCtrSampleEncrypter();
232 
233     // methods
234     virtual AP4_Result EncryptSampleData(AP4_DataBuffer& data_in,
235                                          AP4_DataBuffer& data_out,
236                                          AP4_UI64        bso,
237                                          bool            skip_encryption);
238     virtual AP4_Size   GetEncryptedSampleSize(AP4_Sample& sample);
239 
240 private:
241     // members
242     AP4_CtrStreamCipher* m_Cipher;
243 };
244 
245 /*----------------------------------------------------------------------
246 |   AP4_OmaDcfCbcSampleEncrypter
247 +---------------------------------------------------------------------*/
248 class AP4_OmaDcfCbcSampleEncrypter : public AP4_OmaDcfSampleEncrypter
249 {
250 public:
251     // constructor and destructor
252     AP4_OmaDcfCbcSampleEncrypter(AP4_BlockCipher* block_cipher,
253                                  const AP4_UI08*  salt); // salt is only 8 bytes
254     ~AP4_OmaDcfCbcSampleEncrypter();
255 
256     // methods
257     virtual AP4_Result EncryptSampleData(AP4_DataBuffer& data_in,
258                                          AP4_DataBuffer& data_out,
259                                          AP4_UI64        bso,
260                                          bool            skip_encryption);
261     virtual AP4_Size   GetEncryptedSampleSize(AP4_Sample& sample);
262 
263 private:
264     // members
265     AP4_CbcStreamCipher* m_Cipher;
266 };
267 
268 /*----------------------------------------------------------------------
269 |   AP4_OmaDcfDecryptingProcessor
270 +---------------------------------------------------------------------*/
271 /**
272  *  Use for DCF only, not PDCF. For PDCF, use the
273  * AP4_StandardDecryptingProcessor class
274  */
275 class AP4_OmaDcfDecryptingProcessor : public AP4_Processor
276 {
277 public:
278     // constructor
279     AP4_OmaDcfDecryptingProcessor(const AP4_ProtectionKeyMap* key_map = NULL,
280                                   AP4_BlockCipherFactory*     block_cipher_factory = NULL);
281 
282     // accessors
GetKeyMap()283     AP4_ProtectionKeyMap& GetKeyMap() { return m_KeyMap; }
284 
285     // methods
286     virtual AP4_Result Initialize(AP4_AtomParent&   top_level,
287                                   AP4_ByteStream&   stream,
288                                   ProgressListener* listener);
289 
290 private:
291     // members
292     AP4_BlockCipherFactory* m_BlockCipherFactory;
293     AP4_ProtectionKeyMap    m_KeyMap;
294 };
295 
296 /*----------------------------------------------------------------------
297 |   AP4_OmaDcfEncryptingProcessor
298 +---------------------------------------------------------------------*/
299 class AP4_OmaDcfEncryptingProcessor : public AP4_Processor
300 {
301 public:
302     // constructor
303     AP4_OmaDcfEncryptingProcessor(AP4_OmaDcfCipherMode    cipher_mode,
304                                   AP4_BlockCipherFactory* block_cipher_factory = NULL);
305 
306     // accessors
GetKeyMap()307     AP4_ProtectionKeyMap& GetKeyMap()      { return m_KeyMap;      }
GetPropertyMap()308     AP4_TrackPropertyMap& GetPropertyMap() { return m_PropertyMap; }
309 
310     // AP4_Processor methods
311     virtual AP4_Result Initialize(AP4_AtomParent&   top_level,
312                                   AP4_ByteStream&   stream,
313                                   AP4_Processor::ProgressListener* listener = NULL);
314     virtual AP4_Processor::TrackHandler* CreateTrackHandler(AP4_TrakAtom* trak);
315 
316 private:
317     // members
318     AP4_OmaDcfCipherMode    m_CipherMode;
319     AP4_BlockCipherFactory* m_BlockCipherFactory;
320     AP4_ProtectionKeyMap    m_KeyMap;
321     AP4_TrackPropertyMap    m_PropertyMap;
322 };
323 
324 /*----------------------------------------------------------------------
325 |   AP4_OmaDrmInfo
326 +---------------------------------------------------------------------*/
327 class AP4_OmaDrmInfo
328 {
329 public:
AP4_IMPLEMENT_DYNAMIC_CAST(AP4_OmaDrmInfo)330     AP4_IMPLEMENT_DYNAMIC_CAST(AP4_OmaDrmInfo)
331     virtual ~AP4_OmaDrmInfo() {}
332     virtual const AP4_String& GetContentId()          const = 0;
333     virtual const AP4_String& GetRightsIssuerUrl()    const = 0;
334     virtual const AP4_DataBuffer& GetTextualHeaders() const = 0;
335 };
336 
337 
338 #endif // _AP4_OMA_DCF_H_
339