1 /***************************************************************** 2 | 3 | AP4 - Common Encryption support 4 | 5 | Copyright 2002-2017 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_COMMON_ENCRYPTION_H_ 30 #define _AP4_COMMON_ENCRYPTION_H_ 31 32 /*---------------------------------------------------------------------- 33 | includes 34 +---------------------------------------------------------------------*/ 35 #include "Ap4Atom.h" 36 #include "Ap4ByteStream.h" 37 #include "Ap4Utils.h" 38 #include "Ap4Processor.h" 39 #include "Ap4Protection.h" 40 #include "Ap4PsshAtom.h" 41 42 /*---------------------------------------------------------------------- 43 | class declarations 44 +---------------------------------------------------------------------*/ 45 class AP4_StreamCipher; 46 class AP4_SaizAtom; 47 class AP4_SaioAtom; 48 class AP4_CencSampleInfoTable; 49 class AP4_AvcFrameParser; 50 class AP4_HevcFrameParser; 51 52 /*---------------------------------------------------------------------- 53 | constants 54 +---------------------------------------------------------------------*/ 55 const AP4_UI32 AP4_PROTECTION_SCHEME_TYPE_CENC = AP4_ATOM_TYPE('c','e','n','c'); 56 const AP4_UI32 AP4_PROTECTION_SCHEME_TYPE_CENS = AP4_ATOM_TYPE('c','e','n','s'); 57 const AP4_UI32 AP4_PROTECTION_SCHEME_TYPE_CBC1 = AP4_ATOM_TYPE('c','b','c','1'); 58 const AP4_UI32 AP4_PROTECTION_SCHEME_TYPE_CBCS = AP4_ATOM_TYPE('c','b','c','s'); 59 const AP4_UI32 AP4_PROTECTION_SCHEME_VERSION_CENC_10 = 0x00010000; 60 61 const AP4_UI32 AP4_CENC_CIPHER_NONE = 0; 62 const AP4_UI32 AP4_CENC_CIPHER_AES_128_CTR = 1; 63 const AP4_UI32 AP4_CENC_CIPHER_AES_128_CBC = 2; 64 65 const AP4_UI32 AP4_CENC_SAMPLE_ENCRYPTION_FLAG_OVERRIDE_TRACK_ENCRYPTION_DEFAULTS = 1; 66 const AP4_UI32 AP4_CENC_SAMPLE_ENCRYPTION_FLAG_USE_SUB_SAMPLE_ENCRYPTION = 2; 67 68 typedef enum { 69 AP4_CENC_VARIANT_PIFF_CTR, 70 AP4_CENC_VARIANT_PIFF_CBC, 71 AP4_CENC_VARIANT_MPEG_CENC, 72 AP4_CENC_VARIANT_MPEG_CBC1, 73 AP4_CENC_VARIANT_MPEG_CENS, 74 AP4_CENC_VARIANT_MPEG_CBCS 75 } AP4_CencVariant; 76 77 /*---------------------------------------------------------------------- 78 | AP4_CencTrackEncryption 79 +---------------------------------------------------------------------*/ 80 class AP4_CencTrackEncryption { 81 public: AP4_IMPLEMENT_DYNAMIC_CAST(AP4_CencTrackEncryption)82 AP4_IMPLEMENT_DYNAMIC_CAST(AP4_CencTrackEncryption) 83 84 virtual ~AP4_CencTrackEncryption() {} 85 86 // methods 87 AP4_Result Parse(AP4_ByteStream& stream); 88 AP4_Result DoInspectFields(AP4_AtomInspector& inspector); 89 AP4_Result DoWriteFields(AP4_ByteStream& stream); 90 91 // accessors GetDefaultIsProtected()92 AP4_UI32 GetDefaultIsProtected() { return m_DefaultIsProtected; } GetDefaultPerSampleIvSize()93 AP4_UI08 GetDefaultPerSampleIvSize() { return m_DefaultPerSampleIvSize; } GetDefaultConstantIvSize()94 AP4_UI08 GetDefaultConstantIvSize() { return m_DefaultConstantIvSize; } GetDefaultConstantIv()95 const AP4_UI08* GetDefaultConstantIv() { return m_DefaultConstantIv; } GetDefaultKid()96 const AP4_UI08* GetDefaultKid() { return m_DefaultKid; } GetDefaultCryptByteBlock()97 AP4_UI08 GetDefaultCryptByteBlock() { return m_DefaultCryptByteBlock; } GetDefaultSkipByteBlock()98 AP4_UI08 GetDefaultSkipByteBlock() { return m_DefaultSkipByteBlock; } 99 100 protected: 101 // constructors 102 AP4_CencTrackEncryption(AP4_UI08 version); 103 AP4_CencTrackEncryption(AP4_UI08 version, 104 AP4_UI08 default_is_protected, 105 AP4_UI08 default_per_sample_iv_size, 106 const AP4_UI08* default_kid, 107 AP4_UI08 default_constant_iv_size = 0, 108 const AP4_UI08* default_constant_iv = NULL, 109 AP4_UI08 default_crypt_byte_block = 0, 110 AP4_UI08 default_skip_byte_block = 0); 111 112 private: 113 // members 114 AP4_UI08 m_Version_; // cannot be called m_Version because it would conflict with AP4_Atom::m_Version 115 AP4_UI08 m_DefaultIsProtected; 116 AP4_UI08 m_DefaultPerSampleIvSize; 117 AP4_UI08 m_DefaultConstantIvSize; 118 AP4_UI08 m_DefaultConstantIv[16]; 119 AP4_UI08 m_DefaultKid[16]; 120 AP4_UI08 m_DefaultCryptByteBlock; 121 AP4_UI08 m_DefaultSkipByteBlock; 122 }; 123 124 /*---------------------------------------------------------------------- 125 | AP4_CencSampleEncryption 126 +---------------------------------------------------------------------*/ 127 class AP4_CencSampleEncryption { 128 public: AP4_IMPLEMENT_DYNAMIC_CAST(AP4_CencSampleEncryption)129 AP4_IMPLEMENT_DYNAMIC_CAST(AP4_CencSampleEncryption) 130 131 virtual ~AP4_CencSampleEncryption() {} 132 133 // methods 134 AP4_Result DoInspectFields(AP4_AtomInspector& inspector); 135 AP4_Result DoWriteFields(AP4_ByteStream& stream); 136 137 // accessors GetOuter()138 AP4_Atom& GetOuter() { return m_Outer; } GetAlgorithmId()139 AP4_UI32 GetAlgorithmId() { return m_AlgorithmId; } GetPerSampleIvSize()140 AP4_UI08 GetPerSampleIvSize() { return m_PerSampleIvSize; } 141 AP4_Result SetPerSampleIvSize(AP4_UI08 iv_size); GetConstantIvSize()142 AP4_UI08 GetConstantIvSize() { return m_ConstantIvSize; } 143 AP4_Result SetConstantIvSize(AP4_UI08 iv_size); GetCryptByteBlock()144 AP4_UI08 GetCryptByteBlock() { return m_CryptByteBlock; } GetSkipByteBlock()145 AP4_UI08 GetSkipByteBlock() { return m_SkipByteBlock; } GetConstantIv()146 const AP4_UI08* GetConstantIv() { return m_ConstantIv; } GetKid()147 const AP4_UI08* GetKid() { return m_Kid; } GetSampleInfoCount()148 AP4_Cardinal GetSampleInfoCount() { return m_SampleInfoCount; } 149 AP4_Result AddSampleInfo(const AP4_UI08* iv, AP4_DataBuffer& subsample_info); 150 AP4_Result SetSampleInfosSize(AP4_Size size); 151 AP4_Result CreateSampleInfoTable(AP4_UI08 flags, 152 AP4_UI08 default_crypt_byte_block, 153 AP4_UI08 default_skip_byte_block, 154 AP4_UI08 default_per_sample_iv_size, 155 AP4_UI08 default_constant_iv_size, 156 const AP4_UI08* default_constant_iv, 157 AP4_CencSampleInfoTable*& table); 158 159 protected: 160 // constructors 161 AP4_CencSampleEncryption(AP4_Atom& outer, 162 AP4_UI08 per_sample_iv_size, 163 AP4_UI08 constant_iv_size = 0, 164 const AP4_UI08* constant_iv = NULL, 165 AP4_UI08 crypt_byte_block = 0, 166 AP4_UI08 skip_byte_block = 0); 167 AP4_CencSampleEncryption(AP4_Atom& outer, AP4_Size size, AP4_ByteStream& stream); 168 AP4_CencSampleEncryption(AP4_Atom& outer, 169 AP4_UI32 algorithm_id, 170 AP4_UI08 per_sample_iv_size, 171 const AP4_UI08* kid); 172 173 protected: 174 // members 175 AP4_Atom& m_Outer; 176 AP4_UI32 m_AlgorithmId; 177 AP4_UI08 m_PerSampleIvSize; 178 AP4_UI08 m_ConstantIvSize; 179 AP4_UI08 m_ConstantIv[16]; 180 AP4_UI08 m_CryptByteBlock; 181 AP4_UI08 m_SkipByteBlock; 182 AP4_UI08 m_Kid[16]; 183 AP4_Cardinal m_SampleInfoCount; 184 AP4_DataBuffer m_SampleInfos; 185 unsigned int m_SampleInfoCursor; 186 }; 187 188 /*---------------------------------------------------------------------- 189 | AP4_CencSampleInfoTable 190 +---------------------------------------------------------------------*/ 191 class AP4_CencSampleInfoTable { 192 public: 193 // class methods 194 static AP4_Result Create(AP4_ProtectedSampleDescription* sample_description, 195 AP4_ContainerAtom* traf, 196 AP4_UI32& cipher_type, 197 bool& reset_iv_at_each_subsample, 198 AP4_ByteStream& aux_info_data, 199 AP4_Position aux_info_data_offset, 200 AP4_CencSampleInfoTable*& sample_info_table); 201 202 static AP4_Result Create(AP4_ProtectedSampleDescription* sample_description, 203 AP4_ContainerAtom* traf, 204 AP4_SaioAtom*& saio, 205 AP4_SaizAtom*& saiz, 206 AP4_CencSampleEncryption*& sample_encryption_atom, 207 AP4_UI32& cipher_type, 208 bool& reset_iv_at_each_subsample, 209 AP4_ByteStream& aux_info_data, 210 AP4_Position aux_info_data_offset, 211 AP4_CencSampleInfoTable*& sample_info_table); 212 213 static AP4_Result Create(AP4_UI08 flags, 214 AP4_UI08 crypt_byte_block, 215 AP4_UI08 skip_byte_block, 216 AP4_UI08 per_sample_iv_size, 217 AP4_UI08 constant_iv_size, 218 const AP4_UI08* constant_iv, 219 AP4_ContainerAtom& traf, 220 AP4_SaioAtom& saio, 221 AP4_SaizAtom& saiz, 222 AP4_ByteStream& aux_info_data, 223 AP4_Position aux_info_data_offset, 224 AP4_CencSampleInfoTable*& sample_info_table); 225 226 227 // see note below regarding the serialization format 228 static AP4_Result Create(const AP4_UI08* serialized, 229 unsigned int serialized_size, 230 AP4_CencSampleInfoTable*& sample_info_table); 231 232 // constructor 233 AP4_CencSampleInfoTable(AP4_UI08 flags, 234 AP4_UI08 crypt_byte_block, 235 AP4_UI08 skip_byte_block, 236 AP4_UI32 sample_count, 237 AP4_UI08 iv_size); 238 239 // methods GetFlags()240 AP4_UI08 GetFlags() { return m_Flags; } GetCryptByteBlock()241 AP4_UI08 GetCryptByteBlock() { return m_CryptByteBlock; } GetSkipByteBlock()242 AP4_UI08 GetSkipByteBlock() { return m_SkipByteBlock; } GetSampleCount()243 AP4_UI32 GetSampleCount() { return m_SampleCount; } GetIvSize()244 AP4_UI08 GetIvSize() { return m_IvSize; } 245 AP4_Result SetIv(AP4_Ordinal sample_index, const AP4_UI08* iv); 246 const AP4_UI08* GetIv(AP4_Ordinal sample_index); 247 AP4_Result AddSubSampleData(AP4_Cardinal subsample_count, 248 const AP4_UI08* subsample_data); HasSubSampleInfo()249 bool HasSubSampleInfo() { 250 return m_SubSampleMapStarts.ItemCount() != 0; 251 } GetSubsampleCount(AP4_Cardinal sample_index)252 unsigned int GetSubsampleCount(AP4_Cardinal sample_index) { 253 if (sample_index < m_SampleCount) { 254 return m_SubSampleMapLengths[sample_index]; 255 } else { 256 return 0; 257 } 258 } 259 AP4_Result GetSampleInfo(AP4_Cardinal sample_index, 260 AP4_Cardinal& subsample_count, 261 const AP4_UI16*& bytes_of_cleartext_data, 262 const AP4_UI32*& bytes_of_encrypted_data); 263 264 AP4_Result GetSubsampleInfo(AP4_Cardinal sample_index, 265 AP4_Cardinal subsample_index, 266 AP4_UI16& bytes_of_cleartext_data, 267 AP4_UI32& bytes_of_encrypted_data); 268 269 // see note below regarding the serialization format 270 AP4_Result Serialize(AP4_DataBuffer& buffer); 271 272 private: 273 AP4_UI32 m_SampleCount; 274 AP4_UI08 m_Flags; 275 AP4_UI08 m_CryptByteBlock; 276 AP4_UI08 m_SkipByteBlock; 277 AP4_UI08 m_IvSize; 278 AP4_DataBuffer m_IvData; 279 AP4_Array<AP4_UI16> m_BytesOfCleartextData; 280 AP4_Array<AP4_UI32> m_BytesOfEncryptedData; 281 AP4_Array<unsigned int> m_SubSampleMapStarts; 282 AP4_Array<unsigned int> m_SubSampleMapLengths; 283 }; 284 285 /*---------------------------------------------------------------------- 286 | AP4_CencSampleInfoTable serialization format 287 | 288 | (All integers are stored in big-endian byte order) 289 | 290 | +---------------+----------------+------------------------------------+ 291 | | Size | Type | Description | 292 | +---------------+----------------+------------------------------------+ 293 | 294 | +---------------+----------------+------------------------------------+ 295 | | 4 bytes | 32-bit integer | sample_count | 296 | +---------------+----------------+------------------------------------+ 297 | | 1 byte | 8-bit integer | flags | 298 | +---------------+----------------+------------------------------------+ 299 | | 1 byte | 8-bit integer | crypt_byte_block | 300 | +---------------+----------------+------------------------------------+ 301 | | 1 byte | 8-bit integer | skip_byte_block | 302 | +---------------+----------------+------------------------------------+ 303 | | 1 byte | 8-bit integer | iv_size | 304 | +---------------+----------------+------------------------------------+ 305 | 306 | repeat sample_count times: 307 | +---------------+----------------+------------------------------------+ 308 | | iv_size bytes | byte array | IV[i] | 309 | +---------------+----------------+------------------------------------+ 310 | 311 | +---------------+----------------+------------------------------------+ 312 | | 4 bytes | 32-bit integer | entry_count | 313 | +---------------+----------------+------------------------------------+ 314 | 315 | repeat entry_count times: 316 | +---------------+----------------+------------------------------------+ 317 | | 2 bytes | 16-bit integer | bytes_of_cleartext_data[i] | 318 | +---------------+----------------+------------------------------------+ 319 | 320 | repeat entry_count times: 321 | +---------------+----------------+------------------------------------+ 322 | | 4 bytes | 32-bit integer | bytes_of_encrypted_data[i] | 323 | +---------------+----------------+------------------------------------+ 324 | 325 | +---------------+----------------+------------------------------------+ 326 | | 4 bytes | 32-bit flags | 1 if subsamples are used, 0 if not | 327 | +---------------+----------------+------------------------------------+ 328 | 329 | if subsamples are used, repeat sample_count times: 330 | +---------------+----------------+------------------------------------+ 331 | | 4 bytes | 32-bit integer | subsample_map_start[i] | 332 | +---------------+----------------+------------------------------------+ 333 | 334 | if subsamples are used, repeat sample_count times: 335 | +---------------+----------------+------------------------------------+ 336 | | 4 bytes | 32-bit integer | subsample_map_length[i] | 337 | +---------------+----------------+------------------------------------+ 338 | 339 | NOTES: subsample_map_start[i] ans subsample_map_length[i] are, respectively, 340 | the index and the length the i'th subsample map sequence in the 341 | bytes_of_cleartext_data anb bytes_of_encrypted_data arrays. 342 | For example, if we have: 343 | bytes_of_cleartext_data[] = { 10, 15, 13, 17, 12 } 344 | bytes_of_encrypted_data[] = { 100, 200, 50, 80, 32 } 345 | subsample_map_start = { 0, 3 } 346 | subsample_map_length = { 3, 2 } 347 | It means that the (bytes_of_cleartext_data, bytes_of_encrypted_data) 348 | sequences for the two subsamples are: 349 | subsample[0] --> [(10,100), (15, 200), (13, 50)] 350 | subsample[1] --> [(17, 80), (12, 32)] 351 | 352 +---------------------------------------------------------------------*/ 353 354 355 /*---------------------------------------------------------------------- 356 | AP4_CencSampleEncrypter 357 +---------------------------------------------------------------------*/ 358 class AP4_CencSampleEncrypter 359 { 360 public: 361 // constructor and destructor AP4_CencSampleEncrypter(AP4_StreamCipher * cipher,bool constant_iv)362 AP4_CencSampleEncrypter(AP4_StreamCipher* cipher, 363 bool constant_iv) : 364 m_Cipher(cipher), 365 m_ConstantIv(constant_iv) { 366 AP4_SetMemory(m_Iv, 0, 16); 367 }; 368 virtual ~AP4_CencSampleEncrypter(); 369 370 // methods 371 virtual AP4_Result EncryptSampleData(AP4_DataBuffer& data_in, 372 AP4_DataBuffer& data_out, 373 AP4_DataBuffer& sample_infos) = 0; 374 SetIv(const AP4_UI08 * iv)375 void SetIv(const AP4_UI08* iv) { AP4_CopyMemory(m_Iv, iv, 16); } GetIv()376 const AP4_UI08* GetIv() { return m_Iv; } UseSubSamples()377 virtual bool UseSubSamples() { return false; } GetSubSampleMap(AP4_DataBuffer &,AP4_Array<AP4_UI16> &,AP4_Array<AP4_UI32> &)378 virtual AP4_Result GetSubSampleMap(AP4_DataBuffer& /* sample_data */, 379 AP4_Array<AP4_UI16>& /* bytes_of_cleartext_data */, 380 AP4_Array<AP4_UI32>& /* bytes_of_encrypted_data */) { 381 return AP4_SUCCESS; 382 } 383 384 protected: 385 AP4_UI08 m_Iv[16]; 386 AP4_StreamCipher* m_Cipher; 387 bool m_ConstantIv; 388 }; 389 390 /*---------------------------------------------------------------------- 391 | AP4_CencCtrSampleEncrypter 392 +---------------------------------------------------------------------*/ 393 class AP4_CencCtrSampleEncrypter : public AP4_CencSampleEncrypter 394 { 395 public: 396 // constructor and destructor AP4_CencCtrSampleEncrypter(AP4_StreamCipher * cipher,bool constant_iv,unsigned int iv_size)397 AP4_CencCtrSampleEncrypter(AP4_StreamCipher* cipher, 398 bool constant_iv, 399 unsigned int iv_size) : 400 AP4_CencSampleEncrypter(cipher, constant_iv), 401 m_IvSize(iv_size) {} 402 403 // methods 404 virtual AP4_Result EncryptSampleData(AP4_DataBuffer& data_in, 405 AP4_DataBuffer& data_out, 406 AP4_DataBuffer& sample_infos); 407 408 protected: 409 unsigned int m_IvSize; 410 }; 411 412 /*---------------------------------------------------------------------- 413 | AP4_CencCbcSampleEncrypter 414 +---------------------------------------------------------------------*/ 415 class AP4_CencCbcSampleEncrypter : public AP4_CencSampleEncrypter 416 { 417 public: 418 // constructor and destructor AP4_CencCbcSampleEncrypter(AP4_StreamCipher * cipher,bool constant_iv)419 AP4_CencCbcSampleEncrypter(AP4_StreamCipher* cipher, 420 bool constant_iv) : 421 AP4_CencSampleEncrypter(cipher, constant_iv) {} 422 423 // methods 424 virtual AP4_Result EncryptSampleData(AP4_DataBuffer& data_in, 425 AP4_DataBuffer& data_out, 426 AP4_DataBuffer& sample_infos); 427 }; 428 429 /*---------------------------------------------------------------------- 430 | AP4_CencSubSampleMapper 431 +---------------------------------------------------------------------*/ 432 class AP4_CencSubSampleMapper 433 { 434 public: 435 // constructor and destructor AP4_CencSubSampleMapper(AP4_Size nalu_length_size,AP4_UI32 format)436 AP4_CencSubSampleMapper(AP4_Size nalu_length_size, AP4_UI32 format) : 437 m_NaluLengthSize(nalu_length_size), 438 m_Format(format) {} ~AP4_CencSubSampleMapper()439 virtual ~AP4_CencSubSampleMapper() {} 440 441 // methods 442 virtual AP4_Result GetSubSampleMap(AP4_DataBuffer& sample_data, 443 AP4_Array<AP4_UI16>& bytes_of_cleartext_data, 444 AP4_Array<AP4_UI32>& bytes_of_encrypted_data) = 0; 445 446 protected: 447 // members 448 AP4_Size m_NaluLengthSize; 449 AP4_UI32 m_Format; 450 }; 451 452 /*---------------------------------------------------------------------- 453 | AP4_CencBasicSubSampleMapper 454 +---------------------------------------------------------------------*/ 455 class AP4_CencBasicSubSampleMapper : public AP4_CencSubSampleMapper 456 { 457 public: 458 // constructor and destructor AP4_CencBasicSubSampleMapper(AP4_Size nalu_length_size,AP4_UI32 format)459 AP4_CencBasicSubSampleMapper(AP4_Size nalu_length_size, AP4_UI32 format) : 460 AP4_CencSubSampleMapper(nalu_length_size, format) {} 461 462 // methods 463 virtual AP4_Result GetSubSampleMap(AP4_DataBuffer& sample_data, 464 AP4_Array<AP4_UI16>& bytes_of_cleartext_data, 465 AP4_Array<AP4_UI32>& bytes_of_encrypted_data); 466 }; 467 468 /*---------------------------------------------------------------------- 469 | AP4_CencAdvancedSubSampleMapper 470 +---------------------------------------------------------------------*/ 471 class AP4_CencAdvancedSubSampleMapper : public AP4_CencSubSampleMapper 472 { 473 public: 474 // constructor and destructor AP4_CencAdvancedSubSampleMapper(AP4_Size nalu_length_size,AP4_UI32 format)475 AP4_CencAdvancedSubSampleMapper(AP4_Size nalu_length_size, AP4_UI32 format) : 476 AP4_CencSubSampleMapper(nalu_length_size, format) {} 477 478 // methods 479 virtual AP4_Result GetSubSampleMap(AP4_DataBuffer& sample_data, 480 AP4_Array<AP4_UI16>& bytes_of_cleartext_data, 481 AP4_Array<AP4_UI32>& bytes_of_encrypted_data); 482 }; 483 484 /*---------------------------------------------------------------------- 485 | AP4_CencCbcsSubSampleMapper 486 +---------------------------------------------------------------------*/ 487 class AP4_CencCbcsSubSampleMapper : public AP4_CencSubSampleMapper 488 { 489 public: 490 // constructor and destructor 491 AP4_CencCbcsSubSampleMapper(AP4_Size nalu_length_size, AP4_UI32 format, AP4_TrakAtom* trak); 492 ~AP4_CencCbcsSubSampleMapper(); 493 494 // methods 495 virtual AP4_Result GetSubSampleMap(AP4_DataBuffer& sample_data, 496 AP4_Array<AP4_UI16>& bytes_of_cleartext_data, 497 AP4_Array<AP4_UI32>& bytes_of_encrypted_data); 498 499 private: 500 // members 501 AP4_AvcFrameParser* m_AvcParser; 502 AP4_HevcFrameParser* m_HevcParser; 503 504 // methods 505 AP4_Result ParseAvcData(const AP4_UI08* data, AP4_Size data_size); 506 AP4_Result ParseHevcData(const AP4_UI08* data, AP4_Size data_size); 507 }; 508 509 /*---------------------------------------------------------------------- 510 | AP4_CencSubSampleEncrypter 511 +---------------------------------------------------------------------*/ 512 class AP4_CencSubSampleEncrypter : public AP4_CencSampleEncrypter 513 { 514 public: 515 // constructor and destructor AP4_CencSubSampleEncrypter(AP4_StreamCipher * cipher,bool constant_iv,bool reset_iv_at_each_subsample,AP4_CencSubSampleMapper * subsample_mapper)516 AP4_CencSubSampleEncrypter(AP4_StreamCipher* cipher, 517 bool constant_iv, 518 bool reset_iv_at_each_subsample, 519 AP4_CencSubSampleMapper* subsample_mapper) : 520 AP4_CencSampleEncrypter(cipher, constant_iv), 521 m_ResetIvForEachSubsample(reset_iv_at_each_subsample), 522 m_SubSampleMapper(subsample_mapper) {} ~AP4_CencSubSampleEncrypter()523 virtual ~AP4_CencSubSampleEncrypter() { 524 delete m_SubSampleMapper; 525 } 526 527 // methods UseSubSamples()528 virtual bool UseSubSamples() { return true; } GetSubSampleMap(AP4_DataBuffer & sample_data,AP4_Array<AP4_UI16> & bytes_of_cleartext_data,AP4_Array<AP4_UI32> & bytes_of_encrypted_data)529 virtual AP4_Result GetSubSampleMap(AP4_DataBuffer& sample_data, 530 AP4_Array<AP4_UI16>& bytes_of_cleartext_data, 531 AP4_Array<AP4_UI32>& bytes_of_encrypted_data) { 532 return m_SubSampleMapper->GetSubSampleMap(sample_data, bytes_of_cleartext_data, bytes_of_encrypted_data); 533 } 534 535 // members 536 bool m_ResetIvForEachSubsample; 537 AP4_CencSubSampleMapper* m_SubSampleMapper; 538 }; 539 540 /*---------------------------------------------------------------------- 541 | AP4_CencCtrSubSampleEncrypter 542 +---------------------------------------------------------------------*/ 543 class AP4_CencCtrSubSampleEncrypter : public AP4_CencSubSampleEncrypter 544 { 545 public: 546 // constructor and destructor AP4_CencCtrSubSampleEncrypter(AP4_StreamCipher * cipher,bool constant_iv,bool reset_iv_at_each_subsample,unsigned int iv_size,AP4_CencSubSampleMapper * subsample_mapper)547 AP4_CencCtrSubSampleEncrypter(AP4_StreamCipher* cipher, 548 bool constant_iv, 549 bool reset_iv_at_each_subsample, 550 unsigned int iv_size, 551 AP4_CencSubSampleMapper* subsample_mapper) : 552 AP4_CencSubSampleEncrypter(cipher, 553 constant_iv, 554 reset_iv_at_each_subsample, 555 subsample_mapper), 556 m_IvSize(iv_size) {} 557 558 // methods 559 virtual AP4_Result EncryptSampleData(AP4_DataBuffer& data_in, 560 AP4_DataBuffer& data_out, 561 AP4_DataBuffer& sample_infos); 562 563 protected: 564 unsigned int m_IvSize; 565 }; 566 567 /*---------------------------------------------------------------------- 568 | AP4_CencCbcSubSampleEncrypter 569 +---------------------------------------------------------------------*/ 570 class AP4_CencCbcSubSampleEncrypter : public AP4_CencSubSampleEncrypter 571 { 572 public: 573 // constructor and destructor AP4_CencCbcSubSampleEncrypter(AP4_StreamCipher * cipher,bool constant_iv,bool reset_iv_at_each_subsample,AP4_CencSubSampleMapper * subsample_mapper)574 AP4_CencCbcSubSampleEncrypter(AP4_StreamCipher* cipher, 575 bool constant_iv, 576 bool reset_iv_at_each_subsample, 577 AP4_CencSubSampleMapper* subsample_mapper) : 578 AP4_CencSubSampleEncrypter(cipher, 579 constant_iv, 580 reset_iv_at_each_subsample, 581 subsample_mapper) {} 582 583 // methods 584 virtual AP4_Result EncryptSampleData(AP4_DataBuffer& data_in, 585 AP4_DataBuffer& data_out, 586 AP4_DataBuffer& sample_infos); 587 }; 588 589 /*---------------------------------------------------------------------- 590 | AP4_CencEncryptingProcessor 591 +---------------------------------------------------------------------*/ 592 class AP4_CencEncryptingProcessor : public AP4_Processor 593 { 594 public: 595 // class constants 596 static const AP4_UI32 OPTION_EME_PSSH = 0x01; ///< Include a 'standard EME' pssh atom in the output 597 static const AP4_UI32 OPTION_PIFF_COMPATIBILITY = 0x02; ///< Attempt to create an output that is compatible with the PIFF format 598 static const AP4_UI32 OPTION_PIFF_IV_SIZE_16 = 0x04; ///< With the PIFF-compatibiity option, use an IV of size 16 when possible (instead of 8) 599 static const AP4_UI32 OPTION_IV_SIZE_8 = 0x08; ///< Use an IV of size 8 when possible (instead of 16 by default). 600 static const AP4_UI32 OPTION_NO_SENC = 0x10; ///< Don't output an 'senc' atom 601 602 // types 603 struct Encrypter { EncrypterEncrypter604 Encrypter(AP4_UI32 track_id, AP4_UI32 cleartext_fragments, AP4_CencSampleEncrypter* sample_encrypter) : 605 m_TrackId(track_id), 606 m_CurrentFragment(0), 607 m_CleartextFragments(cleartext_fragments), 608 m_SampleEncrypter(sample_encrypter) {} ~EncrypterEncrypter609 ~Encrypter() { delete m_SampleEncrypter; } 610 AP4_UI32 m_TrackId; 611 AP4_UI32 m_CurrentFragment; 612 AP4_UI32 m_CleartextFragments; 613 AP4_CencSampleEncrypter* m_SampleEncrypter; 614 }; 615 616 // constructor 617 AP4_CencEncryptingProcessor(AP4_CencVariant variant, 618 AP4_UI32 options = 0, 619 AP4_BlockCipherFactory* block_cipher_factory = NULL); 620 ~AP4_CencEncryptingProcessor(); 621 622 // accessors GetKeyMap()623 AP4_ProtectionKeyMap& GetKeyMap() { return m_KeyMap; } GetPropertyMap()624 AP4_TrackPropertyMap& GetPropertyMap() { return m_PropertyMap; } GetPsshAtoms()625 AP4_Array<AP4_PsshAtom*>& GetPsshAtoms() { return m_PsshAtoms; } 626 627 // AP4_Processor methods 628 virtual AP4_Result Initialize(AP4_AtomParent& top_level, 629 AP4_ByteStream& stream, 630 AP4_Processor::ProgressListener* listener = NULL); 631 virtual AP4_Processor::TrackHandler* CreateTrackHandler(AP4_TrakAtom* trak); 632 virtual AP4_Processor::FragmentHandler* CreateFragmentHandler(AP4_TrakAtom* trak, 633 AP4_TrexAtom* trex, 634 AP4_ContainerAtom* traf, 635 AP4_ByteStream& moof_data, 636 AP4_Position moof_offset); 637 638 protected: 639 // members 640 AP4_CencVariant m_Variant; 641 AP4_UI32 m_Options; 642 AP4_BlockCipherFactory* m_BlockCipherFactory; 643 AP4_ProtectionKeyMap m_KeyMap; 644 AP4_TrackPropertyMap m_PropertyMap; 645 AP4_Array<AP4_PsshAtom*> m_PsshAtoms; 646 AP4_List<Encrypter> m_Encrypters; 647 }; 648 649 /*---------------------------------------------------------------------- 650 | AP4_CencDecryptingProcessor 651 +---------------------------------------------------------------------*/ 652 class AP4_CencDecryptingProcessor : public AP4_Processor 653 { 654 public: 655 // constructor 656 AP4_CencDecryptingProcessor(const AP4_ProtectionKeyMap* key_map, 657 AP4_BlockCipherFactory* block_cipher_factory = NULL); 658 659 // AP4_Processor methods 660 virtual AP4_Processor::TrackHandler* CreateTrackHandler(AP4_TrakAtom* trak); 661 virtual AP4_Processor::FragmentHandler* CreateFragmentHandler(AP4_TrakAtom* trak, 662 AP4_TrexAtom* trex, 663 AP4_ContainerAtom* traf, 664 AP4_ByteStream& moof_data, 665 AP4_Position moof_offset); 666 667 protected: 668 // methods 669 const AP4_DataBuffer* GetKeyForTrak(AP4_UI32 track_id, AP4_ProtectedSampleDescription* sample_description); 670 671 // members 672 AP4_BlockCipherFactory* m_BlockCipherFactory; 673 const AP4_ProtectionKeyMap* m_KeyMap; 674 }; 675 676 /*---------------------------------------------------------------------- 677 | AP4_CencSingleSampleDecrypter 678 +---------------------------------------------------------------------*/ 679 class AP4_CencSingleSampleDecrypter 680 { 681 public: 682 static AP4_Result Create(AP4_UI32 cipher_type, 683 const AP4_UI08* key, 684 AP4_Size key_size, 685 AP4_UI08 crypt_byte_block, 686 AP4_UI08 skip_byte_block, 687 AP4_BlockCipherFactory* block_cipher_factory, 688 bool reset_iv_at_each_subsample, 689 AP4_CencSingleSampleDecrypter*& decrypter); 690 691 // methods AP4_CencSingleSampleDecrypter(AP4_StreamCipher * cipher)692 AP4_CencSingleSampleDecrypter(AP4_StreamCipher* cipher) : 693 m_Cipher(cipher), 694 m_FullBlocksOnly(false) {} 695 virtual ~AP4_CencSingleSampleDecrypter(); 696 virtual AP4_Result DecryptSampleData(AP4_DataBuffer& data_in, 697 AP4_DataBuffer& data_out, 698 699 // always 16 bytes 700 const AP4_UI08* iv, 701 702 // pass 0 for full decryption 703 unsigned int subsample_count, 704 705 // array of <subsample_count> integers. NULL if subsample_count is 0 706 const AP4_UI16* bytes_of_cleartext_data, 707 708 // array of <subsample_count> integers. NULL if subsample_count is 0 709 const AP4_UI32* bytes_of_encrypted_data); 710 711 private: 712 // constructor AP4_CencSingleSampleDecrypter(AP4_StreamCipher * cipher,bool full_blocks_only,bool reset_iv_at_each_subsample)713 AP4_CencSingleSampleDecrypter(AP4_StreamCipher* cipher, 714 bool full_blocks_only, 715 bool reset_iv_at_each_subsample) : 716 m_Cipher(cipher), 717 m_FullBlocksOnly(full_blocks_only), 718 m_ResetIvAtEachSubsample(reset_iv_at_each_subsample) {} 719 720 // members 721 AP4_StreamCipher* m_Cipher; 722 bool m_FullBlocksOnly; 723 bool m_ResetIvAtEachSubsample; 724 }; 725 726 /*---------------------------------------------------------------------- 727 | AP4_CencSampleDecrypter 728 +---------------------------------------------------------------------*/ 729 class AP4_CencSampleDecrypter : public AP4_SampleDecrypter 730 { 731 public: 732 static AP4_Result Create(AP4_ProtectedSampleDescription* sample_description, 733 AP4_ContainerAtom* traf, 734 AP4_ByteStream& moof_data, 735 AP4_Position moof_offset, 736 const AP4_UI08* key, 737 AP4_Size key_size, 738 AP4_BlockCipherFactory* block_cipher_factory, 739 AP4_SaioAtom*& saio_atom, // [out] 740 AP4_SaizAtom*& saiz_atom, // [out] 741 AP4_CencSampleEncryption*& sample_encryption_atom, // [out] 742 AP4_CencSampleDecrypter*& decrypter); 743 744 static AP4_Result Create(AP4_ProtectedSampleDescription* sample_description, 745 AP4_ContainerAtom* traf, 746 AP4_ByteStream& moof_data, 747 AP4_Position moof_offset, 748 const AP4_UI08* key, 749 AP4_Size key_size, 750 AP4_BlockCipherFactory* block_cipher_factory, 751 AP4_CencSampleDecrypter*& decrypter); 752 753 static AP4_Result Create(AP4_CencSampleInfoTable* sample_info_table, 754 AP4_UI32 cipher_type, 755 const AP4_UI08* key, 756 AP4_Size key_size, 757 AP4_BlockCipherFactory* block_cipher_factory, 758 bool reset_iv_at_each_subsample, 759 AP4_CencSampleDecrypter*& decrypter); 760 761 // methods AP4_CencSampleDecrypter(AP4_CencSingleSampleDecrypter * single_sample_decrypter,AP4_CencSampleInfoTable * sample_info_table)762 AP4_CencSampleDecrypter(AP4_CencSingleSampleDecrypter* single_sample_decrypter, 763 AP4_CencSampleInfoTable* sample_info_table) : 764 m_SingleSampleDecrypter(single_sample_decrypter), 765 m_SampleInfoTable(sample_info_table), 766 m_SampleCursor(0) {} 767 virtual ~AP4_CencSampleDecrypter(); 768 virtual AP4_Result SetSampleIndex(AP4_Ordinal sample_index); 769 virtual AP4_Result DecryptSampleData(AP4_DataBuffer& data_in, 770 AP4_DataBuffer& data_out, 771 const AP4_UI08* iv); 772 773 protected: 774 AP4_CencSingleSampleDecrypter* m_SingleSampleDecrypter; 775 AP4_CencSampleInfoTable* m_SampleInfoTable; 776 AP4_Ordinal m_SampleCursor; 777 }; 778 779 /*---------------------------------------------------------------------- 780 | AP4_CencSampleEncryptionInformationGroupEntry 781 +---------------------------------------------------------------------*/ 782 class AP4_CencSampleEncryptionInformationGroupEntry { 783 public: 784 AP4_CencSampleEncryptionInformationGroupEntry(const AP4_UI08* data); 785 786 // accessors IsEncrypted()787 bool IsEncrypted() const { return m_IsEncrypted; } GetIvSize()788 AP4_UI08 GetIvSize() const { return m_IvSize; } GetKid()789 const AP4_UI08* GetKid() const { return &m_KID[9]; } 790 791 private: 792 // members 793 bool m_IsEncrypted; 794 AP4_UI08 m_IvSize; 795 AP4_UI08 m_KID[16]; 796 }; 797 798 #endif // _AP4_COMMON_ENCRYPTION_H_ 799