00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef _AP4_STREAM_CIPHER_H_
00030 #define _AP4_STREAM_CIPHER_H_
00031
00032
00033
00034
00035 #include "Ap4Protection.h"
00036 #include "Ap4Results.h"
00037 #include "Ap4Types.h"
00038
00039
00040
00041
00042
00043 const unsigned int AP4_CIPHER_BLOCK_SIZE = 16;
00044
00045
00046
00047
00048 class AP4_StreamCipher
00049 {
00050 public:
00051
00052 typedef enum {
00053 ENCRYPT,
00054 DECRYPT
00055 } CipherDirection;
00056
00057
00058 virtual ~AP4_StreamCipher() {}
00059
00060 virtual AP4_UI64 GetStreamOffset() = 0;
00061
00062 virtual AP4_Result ProcessBuffer(const AP4_UI08* in,
00063 AP4_Size in_size,
00064 AP4_UI08* out,
00065 AP4_Size* out_size,
00066 bool is_last_buffer = false) = 0;
00067
00068
00069
00070
00071 virtual AP4_Result SetStreamOffset(AP4_UI64 offset,
00072 AP4_Cardinal* preroll) = 0;
00073
00074 virtual AP4_Result SetIV(const AP4_UI08* iv) = 0;
00075 virtual const AP4_UI08* GetIV() = 0;
00076 };
00077
00078
00079
00080
00081
00082 class AP4_CtrStreamCipher : public AP4_StreamCipher
00083 {
00084 public:
00085
00086
00091 AP4_CtrStreamCipher(AP4_BlockCipher* block_cipher,
00092 const AP4_UI08* salt,
00093 AP4_Size counter_size);
00094 ~AP4_CtrStreamCipher();
00095
00096
00097 virtual AP4_Result SetStreamOffset(AP4_UI64 offset,
00098 AP4_Cardinal* preroll = NULL);
00099 virtual AP4_UI64 GetStreamOffset() { return m_StreamOffset; }
00100 virtual AP4_Result ProcessBuffer(const AP4_UI08* in,
00101 AP4_Size in_size,
00102 AP4_UI08* out,
00103 AP4_Size* out_size = NULL,
00104 bool is_last_buffer = false);
00105
00106 virtual AP4_Result SetIV(const AP4_UI08* iv);
00107 virtual const AP4_UI08* GetIV() { return m_BaseCounter; }
00108
00109 private:
00110
00111 void SetCounterOffset(AP4_UI32 offset);
00112 void UpdateKeyStream();
00113
00114
00115 AP4_UI64 m_StreamOffset;
00116 AP4_Size m_CounterSize;
00117 AP4_UI08 m_BaseCounter[AP4_CIPHER_BLOCK_SIZE];
00118 AP4_UI08 m_CBlock[AP4_CIPHER_BLOCK_SIZE];
00119 AP4_UI08 m_XBlock[AP4_CIPHER_BLOCK_SIZE];
00120 AP4_BlockCipher* m_BlockCipher;
00121 };
00122
00123
00124
00125
00126 class AP4_CbcStreamCipher : public AP4_StreamCipher
00127 {
00128 public:
00129
00130
00135 AP4_CbcStreamCipher(AP4_BlockCipher* block_cipher, CipherDirection direction);
00136 ~AP4_CbcStreamCipher();
00137
00138
00139 virtual AP4_Result SetStreamOffset(AP4_UI64 offset,
00140 AP4_Cardinal* preroll);
00141 virtual AP4_UI64 GetStreamOffset() { return m_StreamOffset; }
00142 virtual AP4_Result ProcessBuffer(const AP4_UI08* in,
00143 AP4_Size in_size,
00144 AP4_UI08* out,
00145 AP4_Size* out_size,
00146 bool is_last_buffer = false);
00147 virtual AP4_Result SetIV(const AP4_UI08* iv);
00148 virtual const AP4_UI08* GetIV() { return m_Iv; };
00149
00150 private:
00151
00152 CipherDirection m_Direction;
00153 AP4_UI64 m_StreamOffset;
00154 AP4_Size m_OutputSkip;
00155 AP4_UI08 m_InBlockCache[AP4_CIPHER_BLOCK_SIZE];
00156 AP4_UI08 m_OutBlockCache[AP4_CIPHER_BLOCK_SIZE];
00157 AP4_UI08 m_Iv[AP4_CIPHER_BLOCK_SIZE];
00158 AP4_BlockCipher* m_BlockCipher;
00159 bool m_Eos;
00160 AP4_Cardinal m_PrerollByteCount;
00161 };
00162
00163 #endif // _AP4_STREAM_CIPHER_H_