00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef MXFLIB__CRYPTO_H
00030 #define MXFLIB__CRYPTO_H
00031
00032
00033 #include <map>
00034 #include <list>
00035
00036
00037
00038 namespace mxflib
00039 {
00040 }
00041
00042
00043 namespace mxflib
00044 {
00046
00048 class Encrypt_Base : public RefCount<Encrypt_Base>
00049 {
00050 public:
00051 Encrypt_Base() {};
00052 virtual ~Encrypt_Base() {};
00053
00055
00057 bool SetKey(DataChunk &Key) { return SetKey(Key.Size, Key.Data); }
00058
00060
00062 bool SetKey(DataChunkPtr &Key) { return SetKey(Key->Size, Key->Data); }
00063
00065
00067 virtual bool SetKey(size_t KeySize, const UInt8 *Key) = 0;
00068
00070
00077 virtual bool SetIV(size_t IVSize, const UInt8 *IV, bool Force = false) = 0;
00078
00080
00087 bool SetIV(DataChunk &IV, bool Force = false) { return SetIV(IV.Size, IV.Data, Force); }
00088
00090
00097 bool SetIV(DataChunkPtr &IV, bool Force = false) { return SetIV(IV->Size, IV->Data, Force); }
00098
00100
00104 virtual DataChunkPtr GetIV(void) = 0;
00105
00107
00110 virtual bool CanEncryptInPlace(size_t BlockSize = 0) = 0;
00111
00113
00115 virtual bool EncryptInPlace(size_t Size, UInt8 *Data) = 0;
00116
00118
00120 bool EncryptInPlace(DataChunk &Data) { return EncryptInPlace(Data.Size, Data.Data); };
00121
00123
00125 bool EncryptInPlace(DataChunkPtr &Data) { return EncryptInPlace(Data->Size, Data->Data); };
00126
00128
00130 virtual DataChunkPtr Encrypt(size_t Size, const UInt8 *Data) = 0;
00131
00133
00135 DataChunkPtr Encrypt(DataChunk &Data) { return Encrypt(Data.Size, Data.Data); };
00136
00138
00140 DataChunkPtr Encrypt(DataChunkPtr &Data) { return Encrypt(Data->Size, Data->Data); };
00141 };
00142
00143
00144 typedef SmartPtr<Encrypt_Base> EncryptPtr;
00145
00146
00148
00150 class Decrypt_Base : public RefCount<Decrypt_Base>
00151 {
00152 public:
00153 Decrypt_Base() {};
00154 virtual ~Decrypt_Base() {};
00155
00157
00159 bool SetKey(DataChunk &Key) { return SetKey(Key.Size, Key.Data); }
00160
00162
00164 bool SetKey(DataChunkPtr &Key) { return SetKey(Key->Size, Key->Data); }
00165
00167
00169 virtual bool SetKey(size_t KeySize, const UInt8 *Key) = 0;
00170
00172
00179 virtual bool SetIV(size_t IVSize, const UInt8 *IV, bool Force = false) = 0;
00180
00182
00189 bool SetIV(DataChunk &IV, bool Force = false) { return SetIV(IV.Size, IV.Data, Force); }
00190
00192
00199 bool SetIV(DataChunkPtr &IV, bool Force = false) { return SetIV(IV->Size, IV->Data, Force); }
00200
00202
00206 virtual DataChunkPtr GetIV(void) = 0;
00207
00209
00212 virtual bool CanDecryptInPlace(size_t BlockSize = 0) = 0;
00213
00215
00217 virtual bool DecryptInPlace(size_t Size, UInt8 *Data) = 0;
00218
00220
00222 bool DecryptInPlace(DataChunk &Data) { return DecryptInPlace(Data.Size, Data.Data); };
00223
00225
00227 bool DecryptInPlace(DataChunkPtr &Data) { return DecryptInPlace(Data->Size, Data->Data); };
00228
00230
00232 virtual DataChunkPtr Decrypt(size_t Size, const UInt8 *Data) = 0;
00233
00235
00237 DataChunkPtr Decrypt(DataChunk &Data) { return Decrypt(Data.Size, Data.Data); };
00238
00240
00242 DataChunkPtr Decrypt(DataChunkPtr &Data) { return Decrypt(Data->Size, Data->Data); };
00243 };
00244
00245
00246 typedef SmartPtr<Decrypt_Base> DecryptPtr;
00247
00248
00250
00253 class Hash_Base : public RefCount<Hash_Base>
00254 {
00255 public:
00257 Hash_Base() {};
00258
00259
00260 virtual ~Hash_Base() {};
00261
00263
00265 bool SetKey(DataChunk &Key) { return SetKey(Key.Size, Key.Data); }
00266
00268
00270 bool SetKey(DataChunkPtr &Key) { return SetKey(Key->Size, Key->Data); }
00271
00273
00275 virtual bool SetKey(size_t Size, const UInt8 *Key)
00276 {
00277 UNUSED_PARAMETER(Key);
00278 UNUSED_PARAMETER(Size);
00279 return true;
00280 };
00281
00283 void HashData(DataChunk &Data) { HashData(Data.Size, Data.Data); }
00284
00286 void HashData(DataChunkPtr &Data) { HashData(Data->Size, Data->Data); }
00287
00289 virtual void HashData(size_t Size, const UInt8 *Data) = 0;
00290
00292 virtual DataChunkPtr GetHash(void) = 0;
00293 };
00294
00295
00296 typedef SmartPtr<Hash_Base> HashPtr;
00297
00298
00300
00302 class KLVEObject : public KLVObject
00303 {
00304 protected:
00305
00307 enum { EncryptionOverhead = 32 };
00308
00310 enum { EncryptionGranularity = 16 };
00311
00312 EncryptPtr Encrypt;
00313 DecryptPtr Decrypt;
00314 HashPtr WriteHasher;
00315 HashPtr ReadHasher;
00316
00317 bool DataLoaded;
00318 UUIDPtr ContextID;
00319 Length PlaintextOffset;
00320
00324 ULPtr SourceKey;
00325 Length EncryptedLength;
00326 int SourceLengthFormat;
00327 UInt8 IV[16];
00328 UInt8 Check[16];
00329 UUIDPtr TrackFileID;
00330 UInt64 SequenceNumber;
00331 bool HasSequenceNumber;
00332 DataChunkPtr MIC;
00333
00334 size_t DataOffset;
00335
00336 DataChunkPtr EncryptionIV;
00337
00338 Position CurrentReadOffset;
00339 Position CurrentWriteOffset;
00340
00341 int PreDecrypted;
00342 UInt8 PreDecryptBuffer[EncryptionGranularity];
00344
00345 int AwaitingEncryption;
00346 UInt8 AwaitingEncryptionBuffer[EncryptionGranularity];
00348
00349 UInt32 FooterLength;
00350
00351 public:
00352
00353
00355 void SetEncrypt(EncryptPtr NewWrapper) { Encrypt = NewWrapper; };
00356
00358 void SetDecrypt(DecryptPtr NewWrapper) { Decrypt = NewWrapper; };
00359
00361
00363 void SetWriteHasher(HashPtr &Hasher) { WriteHasher = Hasher; };
00364
00366
00368 void SetReadHasher(HashPtr &Hasher) { ReadHasher = Hasher; };
00369
00370
00372
00374 virtual bool SetEncryptIV(size_t IVSize, const UInt8 *IV, bool Force = false)
00375 {
00376 Force = !(!Force);
00377
00378 EncryptionIV = new DataChunk(IVSize, IV);
00379
00380 return true;
00381 }
00382
00384
00386 virtual bool SetDecryptIV(size_t IVSize, const UInt8 *IV, bool Force = false);
00387
00389 virtual DataChunkPtr GetEncryptIV(void);
00390
00392 virtual DataChunkPtr GetDecryptIV(void);
00393
00395 void SetPlaintextOffset(Length Offset) { PlaintextOffset = Offset; }
00396
00398 Length GetPlaintextOffset(void) { return PlaintextOffset; }
00399
00400
00401 KLVEObject(ULPtr ObjectUL);
00402 KLVEObject(KLVObjectPtr &Object);
00403 virtual void Init(void);
00404 virtual ~KLVEObject() {};
00405
00406
00407
00408
00409
00411 virtual ULPtr GetUL(void)
00412 {
00413
00414 if(Decrypt && (!DataLoaded)) LoadData();
00415
00416 return TheUL;
00417 }
00418
00420 virtual void SetUL(ULPtr NewUL) { TheUL = NewUL; }
00421
00423
00426 virtual Int32 GetKLSize(void);
00427
00429 virtual GCElementKind GetGCElementKind(void);
00430
00432 virtual UInt32 GetGCTrackNumber(void);
00433
00435 virtual std::string GetSource(void);
00436
00438
00440 virtual Int32 ReadKL(void);
00441
00443
00446 virtual size_t ReadData(size_t Size = static_cast<size_t>(-1)) { return Base_ReadDataFrom(0, Size); }
00447
00449
00453 virtual size_t ReadDataFrom(Position Offset, size_t Size = static_cast<size_t>(-1));
00454
00456
00460 virtual Int32 WriteKL(Int32 LenSize = 0);
00461
00463
00466 virtual size_t WriteData(size_t Size = static_cast<size_t>(-1)) { return WriteDataFromTo(0, 0, Size); }
00467
00469
00473 virtual size_t WriteDataFrom(Position Start, size_t Size = static_cast<size_t>(-1)) { return WriteDataFromTo(0, Start, Size); }
00474
00476
00480 virtual size_t WriteDataTo(Position Offset, size_t Size = static_cast<size_t>(-1)) { return WriteDataFromTo(Offset, 0, Size); }
00481
00483
00488 virtual size_t WriteDataFromTo(Position Offset, Position Start, size_t Size = static_cast<size_t>(-1))
00489 {
00490
00491 Length BytesToWrite = Data.Size - Start;
00492
00493
00494 if((Size != static_cast<size_t>(-1)) && (Size < BytesToWrite)) BytesToWrite = Size;
00495
00496
00497 if((sizeof(size_t) < 8) && (BytesToWrite > 0xffffffff))
00498 {
00499 error("Tried to write > 4GBytes, but this platform can only handle <= 4GByte chunks\n");
00500 return 0;
00501 }
00502
00503 return WriteDataTo(&Data.Data[Start], Offset, static_cast<size_t>(BytesToWrite));
00504 }
00505
00507
00514 virtual size_t WriteDataTo(const UInt8 *Buffer, Position Offset, size_t Size);
00515
00517 virtual Length GetLength(void)
00518 {
00519 return ValueLength;
00520 }
00521
00523 virtual void SetLength(Length NewLength)
00524 {
00525 ValueLength = NewLength;
00526
00527
00528 EncryptedLength = (ValueLength + EncryptionGranularity) / EncryptionGranularity;
00529 EncryptedLength *= EncryptionGranularity;
00530 }
00531
00533 void SetContextID(UUIDPtr &Context) { ContextID = Context; }
00534
00536 UUIDPtr &GetContextID(void) { return ContextID; }
00537
00538 protected:
00540
00543 bool LoadData(void);
00544
00546
00548 bool ReadFooter(void);
00549
00551
00552 UInt32 CalcFooterLength(void);
00553
00555
00557 bool WriteFooter(void);
00558
00560
00566 size_t ReadCryptoDataFrom(Position Offset, size_t Size = static_cast<size_t>(-1));
00567
00569
00575 size_t ReadChunkedCryptoDataFrom(Position Offset, size_t Size);
00576
00578
00585 size_t WriteCryptoDataTo(const UInt8 *Buffer, Position Offset, size_t Size);
00586 };
00587
00589
00593 class KLVEObjectPtr : public SmartPtr<KLVEObject>
00594 {
00595 public:
00597 KLVEObjectPtr() : SmartPtr<KLVEObject>() {}
00598
00600 KLVEObjectPtr(IRefCount<KLVObject> * ptr) : SmartPtr<KLVEObject>((IRefCount<KLVEObject>*)ptr) {};
00601
00603 KLVEObjectPtr & operator = (IRefCount<KLVObject> * ptr) {__Assign((IRefCount<KLVEObject>*)ptr); return *this;}
00604 };
00605 }
00606
00607
00608 #endif // MXFLIB__CRYPTO_H