crypto.h

Go to the documentation of this file.
00001 
00007 /*
00008  *  Copyright (c) 2004, Matt Beard
00009  *
00010  *  This software is provided 'as-is', without any express or implied warranty.
00011  *  In no event will the authors be held liable for any damages arising from
00012  *  the use of this software.
00013  *
00014  *  Permission is granted to anyone to use this software for any purpose,
00015  *  including commercial applications, and to alter it and redistribute it
00016  *  freely, subject to the following restrictions:
00017  *
00018  *    1. The origin of this software must not be misrepresented; you must
00019  *       not claim that you wrote the original software. If you use this
00020  *       software in a product, an acknowledgment in the product
00021  *       documentation would be appreciated but is not required.
00022  *  
00023  *    2. Altered source versions must be plainly marked as such, and must
00024  *       not be misrepresented as being the original software.
00025  *  
00026  *    3. This notice may not be removed or altered from any source
00027  *       distribution.
00028  */
00029 #ifndef MXFLIB__CRYPTO_H
00030 #define MXFLIB__CRYPTO_H
00031 
00032 
00033 #include <map>
00034 #include <list>
00035 
00036 
00037 // Forward refs
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     // Smart pointer to an encryption wrapper object
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     // Smart pointer to a decryption wrapper object
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         // Virtual base destructor to allow polymorphic destruction
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     // Smart pointer to a hash function wrapper object
00296     typedef SmartPtr<Hash_Base> HashPtr;
00297 
00298 
00300 
00302     class KLVEObject : public KLVObject
00303     {
00304     protected:
00305         /* Some useful constants */
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         //** KLVEObject Specifics **//
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);      // Unused parameter
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         //** Construction / desctruction **//
00401         KLVEObject(ULPtr ObjectUL);             
00402         KLVEObject(KLVObjectPtr &Object);       
00403         virtual void Init(void);
00404         virtual ~KLVEObject() {};
00405 
00406 
00407         //** KLVObject interfaces **//
00408         /* DRAGONS: We should prune these and fall back where possible? */
00409 
00411         virtual ULPtr GetUL(void) 
00412         { 
00413             // If we are decrypting, ensure we know the proper plaintext UL
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             // Calculate default number of bytes to write
00491             Length BytesToWrite = Data.Size - Start;
00492 
00493             // Write the requested size (if valid)
00494             if((Size != static_cast<size_t>(-1)) && (Size < BytesToWrite)) BytesToWrite = Size;
00495 
00496             // Sanity check the size of this chunk
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             // Update encrypted length to take account of padding
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

Generated on Mon Apr 2 15:20:51 2007 for MXFLib by  doxygen 1.5.1-p1